hostsupport/hostopengles20/src/GLES2/fbo.c
branchbug235_bringup_0
changeset 53 c2ef9095503a
parent 20 d2d6724aef32
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2  *
       
     3  * Permission is hereby granted, free of charge, to any person obtaining a
       
     4  * copy of this software and associated documentation files (the "Software"),
       
     5  * to deal in the Software without restriction, including without limitation
       
     6  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
       
     7  * and/or sell copies of the Software, and to permit persons to whom the
       
     8  * Software is furnished to do so, subject to the following conditions:
       
     9  *
       
    10  * The above copyright notice and this permission notice shall be included
       
    11  * in all copies or substantial portions of the Software.
       
    12  *
       
    13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
       
    14  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
       
    16  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
       
    17  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
       
    18  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
       
    19  *
       
    20  * Initial Contributors:
       
    21  * Nokia Corporation - initial contribution.
       
    22  *
       
    23  * Contributors:
       
    24  *
       
    25  * Description:
       
    26  *
       
    27  */
       
    28 
       
    29 #include "common.h"
       
    30 #include "hgl.h"
       
    31 #include "context.h"
       
    32 
       
    33 DGLRenderbuffer* DGLRenderbuffer_create(GLuint name)
       
    34 {
       
    35 	DGLRenderbuffer* buffer = malloc(sizeof(DGLRenderbuffer));
       
    36 	if(buffer == NULL)
       
    37 	{
       
    38 		return NULL;
       
    39 	}
       
    40 
       
    41 	buffer->obj.name = name;
       
    42 	buffer->obj.next = NULL;
       
    43 
       
    44 	buffer->egl_image = NULL;
       
    45 
       
    46 	return buffer;
       
    47 }
       
    48 
       
    49 void DGLRenderbuffer_destroy(DGLRenderbuffer *buffer)
       
    50 {
       
    51 	DGLES2_ASSERT(buffer != NULL);
       
    52 	if(buffer->egl_image != NULL)
       
    53 	{
       
    54 		deglUnregisterImageTarget(buffer->egl_image, GL_RENDERBUFFER, buffer->obj.name);
       
    55 		buffer->egl_image = NULL;
       
    56 	}
       
    57 	free(buffer);
       
    58 }
       
    59 
       
    60 GL_APICALL_BUILD void GL_APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer)
       
    61 {
       
    62 	DGLES2_ENTER();
       
    63 	DGLContext_getHostError(ctx);
       
    64 	ctx->hgl.BindFramebufferEXT(target, framebuffer);
       
    65 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
    66 	{
       
    67 		ctx->framebuffer_binding = framebuffer;
       
    68 	}
       
    69 	DGLES2_LEAVE();
       
    70 }
       
    71 
       
    72 GL_APICALL_BUILD void GL_APIENTRY glBindRenderbuffer(GLenum target, GLuint renderbuffer)
       
    73 {
       
    74 	DGLES2_ENTER();
       
    75 	DGLContext_getHostError(ctx);
       
    76 	ctx->hgl.BindRenderbufferEXT(target, renderbuffer);
       
    77 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
    78 	{
       
    79 		if(!DGLContext_bindRenderbuffer(ctx, renderbuffer))
       
    80 		{
       
    81 			DGLES2_ERROR(GL_OUT_OF_MEMORY);
       
    82 		}
       
    83 	}
       
    84 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
    85 }
       
    86 
       
    87 GL_APICALL_BUILD GLenum GL_APIENTRY glCheckFramebufferStatus(GLenum target)
       
    88 {
       
    89 	DGLES2_ENTER_RET(GL_FALSE);
       
    90 	DGLES2_LEAVE_RET(ctx->hgl.CheckFramebufferStatusEXT(target));
       
    91 }
       
    92 
       
    93 GL_APICALL_BUILD void GL_APIENTRY glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
       
    94 {
       
    95 	DGLES2_ENTER();
       
    96 	DGLContext_getHostError(ctx);
       
    97 	ctx->hgl.DeleteFramebuffersEXT(n, framebuffers);
       
    98 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
    99 	{
       
   100 		// Unbind framebuffer when deleted.
       
   101 		int i;
       
   102 		for(i = 0; i < n; i++)
       
   103 		{
       
   104 			if(ctx->framebuffer_binding == framebuffers[i])
       
   105 			{
       
   106 				ctx->framebuffer_binding = 0;
       
   107 				break;
       
   108 			}
       
   109 		}
       
   110 	}
       
   111 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   112 }
       
   113 
       
   114 GL_APICALL_BUILD void GL_APIENTRY glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
       
   115 {
       
   116 	DGLES2_ENTER();
       
   117 	DGLContext_getHostError(ctx);
       
   118 	ctx->hgl.DeleteRenderbuffersEXT(n, renderbuffers);
       
   119 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   120 	{
       
   121 		int i;
       
   122 		for(i = 0; i < n; i++)
       
   123 		{
       
   124 			DGLContext_destroyRenderbuffer(ctx, renderbuffers[n]);
       
   125 		}
       
   126 	}
       
   127 	DGLES2_LEAVE();
       
   128 }
       
   129 
       
   130 GL_APICALL_BUILD void GL_APIENTRY glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
       
   131 {
       
   132 	DGLES2_ENTER();
       
   133 	DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 &&
       
   134 					attachment != GL_DEPTH_ATTACHMENT &&
       
   135 					attachment != GL_STENCIL_ATTACHMENT,
       
   136 					GL_INVALID_ENUM);
       
   137 	ctx->hgl.FramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer);
       
   138 	DGLES2_LEAVE();
       
   139 }
       
   140 
       
   141 GL_APICALL_BUILD void GL_APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
       
   142 {
       
   143 	DGLES2_ENTER();
       
   144 	DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 &&
       
   145 					attachment != GL_DEPTH_ATTACHMENT &&
       
   146 					attachment != GL_STENCIL_ATTACHMENT,
       
   147 					GL_INVALID_ENUM);
       
   148 	ctx->hgl.FramebufferTexture2DEXT(target, attachment, textarget, texture, level);
       
   149 	DGLES2_LEAVE();
       
   150 }
       
   151 
       
   152 GL_APICALL_BUILD void GL_APIENTRY glGenFramebuffers(GLsizei n, GLuint* framebuffers)
       
   153 {
       
   154 	DGLES2_ENTER();
       
   155 	ctx->hgl.GenFramebuffersEXT(n, framebuffers);
       
   156 	DGLES2_LEAVE();
       
   157 }
       
   158 
       
   159 GL_APICALL_BUILD void GL_APIENTRY glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
       
   160 {
       
   161 	DGLES2_ENTER();
       
   162 	ctx->hgl.GenRenderbuffersEXT(n, renderbuffers);
       
   163 	DGLES2_LEAVE();
       
   164 }
       
   165 
       
   166 GL_APICALL_BUILD void GL_APIENTRY glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
       
   167 {
       
   168 	DGLES2_ENTER();
       
   169 	DGLES2_ERROR_IF(attachment != GL_COLOR_ATTACHMENT0 &&
       
   170 					attachment != GL_DEPTH_ATTACHMENT &&
       
   171 					attachment != GL_STENCIL_ATTACHMENT,
       
   172 					GL_INVALID_ENUM);
       
   173 	DGLES2_ERROR_IF(pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE &&
       
   174 					pname != GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME &&
       
   175 					pname != GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL &&
       
   176 					pname != GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
       
   177 					GL_INVALID_ENUM);
       
   178 	ctx->hgl.GetFramebufferAttachmentParameterivEXT(target, attachment, pname, params);
       
   179 	DGLES2_LEAVE();
       
   180 }
       
   181 
       
   182 GL_APICALL_BUILD void GL_APIENTRY glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
       
   183 {
       
   184 	DGLES2_ENTER();
       
   185 	ctx->hgl.GetRenderbufferParameterivEXT(target, pname, params);
       
   186 	DGLES2_LEAVE();
       
   187 }
       
   188 
       
   189 GL_APICALL_BUILD GLboolean GL_APIENTRY glIsFramebuffer(GLuint framebuffer)
       
   190 {
       
   191 	DGLES2_ENTER_RET(GL_FALSE);
       
   192 	ctx->hgl.IsFramebufferEXT(framebuffer);
       
   193 	DGLES2_LEAVE_RET(GL_FALSE);
       
   194 }
       
   195 
       
   196 GL_APICALL_BUILD GLboolean    GL_APIENTRY glIsRenderbuffer(GLuint renderbuffer)
       
   197 {
       
   198 	DGLES2_ENTER_RET(GL_FALSE);
       
   199 	ctx->hgl.IsRenderbufferEXT(renderbuffer);
       
   200 	DGLES2_LEAVE_RET(GL_FALSE);
       
   201 }
       
   202 
       
   203 GL_APICALL_BUILD void GL_APIENTRY glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
       
   204 {
       
   205 	DGLES2_ENTER();
       
   206 	
       
   207 	switch(internalformat)
       
   208 	{
       
   209 		case GL_DEPTH_COMPONENT16:
       
   210 		case GL_RGBA4:
       
   211 		case GL_RGB5_A1:
       
   212 		case GL_STENCIL_INDEX8:
       
   213 			break;
       
   214 
       
   215 		case GL_RGB565:	// RGB565 is not supported in desktop GL.
       
   216 			internalformat = GL_RGB8;
       
   217 			break;
       
   218 
       
   219 		case GL_DEPTH_COMPONENT24_OES: // extension GL_OES_depth24
       
   220 			internalformat = GL_DEPTH_COMPONENT24;
       
   221 			break;
       
   222 
       
   223 		case GL_DEPTH_COMPONENT32_OES: // extension GL_OES_depth32
       
   224 			internalformat = GL_DEPTH_COMPONENT32;
       
   225 			break;
       
   226 
       
   227 		case GL_RGB8_OES: // extension GL_OES_rgb8_rgba8
       
   228 			internalformat = GL_RGB8;
       
   229 			break;
       
   230 
       
   231 		case GL_RGBA8_OES: // extension GL_OES_rgb8_rgba8
       
   232 			internalformat = GL_RGBA8;
       
   233 			break;
       
   234 	}
       
   235 	
       
   236 	DGLContext_getHostError(ctx);
       
   237 	ctx->hgl.RenderbufferStorageEXT(target, internalformat, width, height);
       
   238 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   239 	{
       
   240 		DGLRenderbuffer* buffer = DGLContext_findRenderbuffer(ctx, ctx->renderbuffer_binding);
       
   241 		DGLES2_ASSERT(buffer != NULL);
       
   242 		if(buffer->egl_image != NULL)
       
   243 		{
       
   244 			// Renderbuffer is respecified. It is no longer an EGLImage sibling.
       
   245 			deglUnregisterImageTarget(buffer->egl_image, GL_RENDERBUFFER, buffer->obj.name);
       
   246 			buffer->egl_image = NULL;
       
   247 		}
       
   248 	}
       
   249 
       
   250 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   251 }
       
   252 
       
   253 GL_APICALL_BUILD void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
       
   254 {
       
   255 	DGLES2_ENTER();
       
   256 	DGLES2_ERROR_IF(target != GL_RENDERBUFFER, GL_INVALID_ENUM);
       
   257 	DGLES2_ERROR_IF(image == NULL, GL_INVALID_OPERATION);
       
   258 	DGLContext_getHostError(ctx);
       
   259 	if(!DGLContext_specifyRenderbufferFromEGLImage(ctx, image))
       
   260 	{
       
   261 		DGLES2_ERROR(GL_INVALID_OPERATION);
       
   262 	}
       
   263 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   264 }