hostsupport/hostopengles20/src/texture.c
branchbug235_bringup_0
changeset 55 09263774e342
parent 53 c2ef9095503a
child 76 24381b61de5c
equal deleted inserted replaced
54:067180f57b12 55:09263774e342
       
     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 #include "half.h"
       
    33 #include "util.h"
       
    34 #include "degl.h"
       
    35 
       
    36 DGLTexture* DGLTexture_create(GLuint name, DGLTextureType type, GLint num_levels)
       
    37 {
       
    38 	DGLTexture* texture = malloc(sizeof(DGLTexture));
       
    39 	if(texture == NULL)
       
    40 	{
       
    41 		return NULL;
       
    42 	}
       
    43 
       
    44 	texture->obj.name = name;
       
    45 	texture->obj.next = NULL;
       
    46 
       
    47 	texture->type = type;
       
    48 
       
    49 	{
       
    50 		int face;
       
    51 		for(face = 0; face < 6; face++)
       
    52 		{
       
    53 			texture->num_levels[face] = 0;
       
    54 			texture->levels[face] = malloc(num_levels * sizeof(DGLTextureLevel));
       
    55 			if(texture->levels[face] == NULL)
       
    56 			{
       
    57 				while(face--)
       
    58 				{
       
    59 					free(texture->levels[face]);
       
    60 				}
       
    61 				free(texture);
       
    62 				return NULL;
       
    63 			}
       
    64 			{
       
    65 				int level;
       
    66 				for(level = 0; level < num_levels; level++)
       
    67 				{
       
    68 					texture->levels[face][level].specified = GL_FALSE;
       
    69 					texture->levels[face][level].format = 0;
       
    70 					texture->levels[face][level].width = 0;
       
    71 					texture->levels[face][level].height = 0;
       
    72 					texture->levels[face][level].bound_surface = NULL;
       
    73 				}
       
    74 			}
       
    75 			texture->egl_image[face] = NULL;
       
    76 		}
       
    77 	}
       
    78 
       
    79 	return texture;
       
    80 }
       
    81 
       
    82 static GLenum dglFaceToTarget(DGLTexture* texture, int face)
       
    83 {
       
    84 	DGLES2_ASSERT(texture != NULL);
       
    85 	{
       
    86 		switch(face)
       
    87 		{
       
    88 			case 0:
       
    89 				if(texture->type == DGLES2_TEXTURE_2D)
       
    90 				{
       
    91 					return GL_TEXTURE_2D;
       
    92 				}
       
    93 				else
       
    94 				{
       
    95 					DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
    96 					return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
       
    97 				}
       
    98 
       
    99 			case 1:
       
   100 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   101 				return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
       
   102 
       
   103 			case 2:
       
   104 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   105 				return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
       
   106 
       
   107 			case 3:
       
   108 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   109 				return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
       
   110 
       
   111 			case 4:
       
   112 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   113 				return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
       
   114 
       
   115 			case 5:
       
   116 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   117 				return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
       
   118 
       
   119 			default:
       
   120 				DGLES2_ASSERT(GL_FALSE);
       
   121 				return -1;
       
   122 		}
       
   123 	}
       
   124 }
       
   125 
       
   126 void DGLTexture_destroy(DGLTexture *texture)
       
   127 {
       
   128 	DGLES2_ASSERT(texture != NULL);
       
   129 	{
       
   130 		int face;
       
   131 		for(face = 0; face < 6; face++)
       
   132 		{
       
   133 			DGLES2_ASSERT(texture->levels[face] != NULL);
       
   134 			free(texture->levels[face]);
       
   135 			texture->levels[face] = NULL;
       
   136 
       
   137 			if(texture->egl_image[face] != NULL)
       
   138 			{
       
   139 				deglUnregisterImageTarget(texture->egl_image[face], dglFaceToTarget(texture, face), texture->obj.name);
       
   140 				texture->egl_image[face] = NULL;
       
   141 			}
       
   142 		}
       
   143 	}
       
   144 	free(texture);
       
   145 }
       
   146 
       
   147 GLboolean DGLTexture_isComplete(const DGLTexture* texture)
       
   148 {
       
   149 	DGLES2_ASSERT(texture != NULL);
       
   150 	{
       
   151 		int num_faces = 6 ? texture->type == DGLES2_TEXTURE_CUBE_MAP : 1;
       
   152 		int face;
       
   153 		for(face = 0; face < num_faces; face++)
       
   154 		{
       
   155 			if(texture->num_levels[face] < 1)
       
   156 			{
       
   157 				return GL_FALSE;
       
   158 			}
       
   159 			else
       
   160 			{
       
   161 				int i;
       
   162 				const DGLTextureLevel* level_zero;
       
   163 				int width;
       
   164 				int height;
       
   165 
       
   166 				level_zero = &texture->levels[face][0];
       
   167 				width = level_zero->width;
       
   168 				height = level_zero->height;
       
   169 
       
   170 				if(width <= 0 || height <= 0)
       
   171 				{
       
   172 					return GL_FALSE;
       
   173 				}
       
   174 
       
   175 				for(i = 1; i < texture->num_levels[face]; i++)
       
   176 				{
       
   177 					const DGLTextureLevel* level = &texture->levels[face][i];
       
   178 
       
   179 					if(width > 1) width /= 2;
       
   180 					if(height > 1) height /= 2;
       
   181 
       
   182 					if(level->format != level_zero->format ||
       
   183 					   level->width != width ||
       
   184 					   level->height != height ||
       
   185 					   level->width == 0 ||
       
   186 					   level->height == 0)
       
   187 					{
       
   188 						return GL_FALSE;
       
   189 					}
       
   190 				}
       
   191 			}
       
   192 		}
       
   193 
       
   194 		return GL_TRUE;
       
   195 	}
       
   196 }
       
   197 
       
   198 GLboolean DGLTexture_hasLevelZero(const DGLTexture* texture)
       
   199 {
       
   200 	DGLES2_ASSERT(texture != NULL);
       
   201 	{
       
   202 		int num_faces = 6 ? texture->type == DGLES2_TEXTURE_CUBE_MAP : 1;
       
   203 		int face;
       
   204 		for(face = 0; face < num_faces; face++)
       
   205 		{
       
   206 			if(texture->num_levels[face] <= 0 || !texture->levels[face][0].specified)
       
   207 			{
       
   208 				return GL_FALSE;
       
   209 			}
       
   210 		}
       
   211 
       
   212 		return GL_TRUE;
       
   213 	}
       
   214 }
       
   215 
       
   216 GLboolean DGLTexture_hasLevelsOtherThanZero(const DGLTexture* texture)
       
   217 {
       
   218 	DGLES2_ASSERT(texture != NULL);
       
   219 	{
       
   220 		int num_faces = 6 ? texture->type == DGLES2_TEXTURE_CUBE_MAP : 1;
       
   221 		int face;
       
   222 		for(face = 0; face < num_faces; face++)
       
   223 		{
       
   224 			int level;
       
   225 			for(level = 1; level < texture->num_levels[face]; level++)
       
   226 			{
       
   227 				if(texture->levels[face][level].specified)
       
   228 				{
       
   229 					return GL_TRUE;
       
   230 				}
       
   231 			}
       
   232 		}
       
   233 
       
   234 		return GL_FALSE;
       
   235 	}
       
   236 }
       
   237 
       
   238 static int dglTargetToFace(DGLTexture* texture, GLenum target)
       
   239 {
       
   240 	DGLES2_ASSERT(texture != NULL);
       
   241 	{
       
   242 		switch(target)
       
   243 		{
       
   244 			case GL_TEXTURE_2D:
       
   245 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_2D);
       
   246 				return 0;
       
   247 
       
   248 			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
       
   249 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   250 				return 0;
       
   251 
       
   252 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
       
   253 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   254 				return 1;
       
   255 
       
   256 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
       
   257 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   258 				return 2;
       
   259 
       
   260 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
       
   261 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   262 				return 3;
       
   263 
       
   264 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
       
   265 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   266 				return 4;
       
   267 
       
   268 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
       
   269 				DGLES2_ASSERT(texture->type == DGLES2_TEXTURE_CUBE_MAP);
       
   270 				return 5;
       
   271 
       
   272 			default:
       
   273 				DGLES2_ASSERT(GL_FALSE);
       
   274 				return -1;
       
   275 		}
       
   276 	}
       
   277 }
       
   278 
       
   279 DGLTextureLevel* DGLTexture_getLevel(DGLTexture* texture, GLenum target, GLint level)
       
   280 {	
       
   281 	DGLES2_ASSERT(texture != NULL);
       
   282 	return &texture->levels[dglTargetToFace(texture, target)][level];
       
   283 }
       
   284 
       
   285 void DGLTexture_setLevel(DGLTexture* texture, GLenum target, GLint level, GLenum format, GLsizei width, GLsizei height)
       
   286 {
       
   287 	DGLES2_ASSERT(texture != NULL);
       
   288 	{
       
   289 		DGLTextureLevel* level_obj = DGLTexture_getLevel(texture, target, level);
       
   290 		level_obj->format = format;
       
   291 		level_obj->width = width;
       
   292 		level_obj->height = height;
       
   293 		level_obj->specified = GL_TRUE;
       
   294 	}
       
   295 }
       
   296 
       
   297 GLeglImageOES DGLTexture_getEGLImage(DGLTexture* texture, GLenum target)
       
   298 {
       
   299 	return texture->egl_image[dglTargetToFace(texture, target)];
       
   300 }
       
   301 
       
   302 void DGLTexture_setEGLImage(DGLTexture* texture, GLenum target, GLeglImageOES image)
       
   303 {
       
   304 	texture->egl_image[dglTargetToFace(texture, target)] = image;
       
   305 }
       
   306 
       
   307 void DGLTexture_generateMipmap(DGLTexture* texture)
       
   308 {
       
   309 	DGLES2_ASSERT(texture != NULL);
       
   310 	{
       
   311 		int face;
       
   312 		int num_faces;
       
   313 		const DGLTextureLevel* level_zero;
       
   314 		int level;
       
   315 		int num_levels;
       
   316 		int width, height;
       
   317 
       
   318 		num_faces = 6 ? texture->type == DGLES2_TEXTURE_CUBE_MAP : 1;
       
   319 		for(face = 0; face < num_faces; face++)
       
   320 		{
       
   321 			level_zero = &texture->levels[face][0];
       
   322 
       
   323 			num_levels = dglLog2(dglMax(level_zero->width, level_zero->height)) + 1;
       
   324 			texture->num_levels[face] = num_levels;
       
   325 
       
   326 			width = level_zero->width;
       
   327 			height = level_zero->height;
       
   328 
       
   329 			for(level = 0; level < num_levels; level++)
       
   330 			{
       
   331 				if(width > 1) width /= 2;
       
   332 				if(height > 1) height /= 2;
       
   333 
       
   334 				DGLES2_ASSERT(level < num_levels - 1 || (width > 1 || height > 1));
       
   335 
       
   336 				if(texture->levels[face][level].bound_surface != NULL)
       
   337 				{
       
   338 					// Texture image is respecified. Release the bound EGLSurface.
       
   339 					deglReleaseTexImage(texture->levels[face][level].bound_surface, texture->obj.name, level);
       
   340 				}
       
   341 
       
   342 				texture->levels[face][level].format = level_zero->format;
       
   343 				texture->levels[face][level].width = width;
       
   344 				texture->levels[face][level].height = height;
       
   345 				texture->levels[face][level].bound_surface = NULL;
       
   346 				texture->levels[face][level].specified = GL_TRUE;
       
   347 			}
       
   348 		}
       
   349 	}
       
   350 }
       
   351 
       
   352 // Add a 3-bit two's complement integer to an integer.
       
   353 static int dglAddTwosComplement(int a, char b)
       
   354 {
       
   355 	if(b & 0x4)
       
   356 	{
       
   357 		// Negative.
       
   358 		return a - ((~b + 1) & 0x7);
       
   359 	}
       
   360 	else
       
   361 	{
       
   362 		// Positive.
       
   363 		return a + b;
       
   364 	}
       
   365 }
       
   366 
       
   367 static int dglClamp(int x, int min, int max)
       
   368 {
       
   369 	if(x < min)
       
   370 	{
       
   371 		return min;
       
   372 	}
       
   373 	else if(x > max)
       
   374 	{
       
   375 		return max;
       
   376 	}
       
   377 	else
       
   378 	{
       
   379 		return x;
       
   380 	}
       
   381 }
       
   382 
       
   383 static void* dglDecompressETCTexture(int width, int height, const unsigned char* data)
       
   384 {
       
   385 	int bytes_per_pixel = 3; // RGB888
       
   386 
       
   387 	unsigned char* decompressed = malloc(width * height * bytes_per_pixel);
       
   388 	if(decompressed == NULL)
       
   389 	{
       
   390 		return NULL;
       
   391 	}
       
   392 	
       
   393 	{
       
   394 		int xblock, yblock;
       
   395 
       
   396 		char dr, dg, db;
       
   397 
       
   398 		// Number of 4x4 blocks horizontally and vertically.
       
   399 		int num_xblocks = (width + 3) / 4;
       
   400 		int num_yblocks = (height + 3) / 4;
       
   401 
       
   402 		for(yblock = 0; yblock < num_yblocks; yblock++)
       
   403 		{
       
   404 			for(xblock = 0; xblock < num_xblocks; xblock++)
       
   405 			{
       
   406 				int i;
       
   407 				char pixel;
       
   408 
       
   409 				khronos_int64_t blockbits;
       
   410 				int diffbit, flipbit;
       
   411 
       
   412 				unsigned char r[2], g[2], b[2];
       
   413 
       
   414 				int table[2];
       
   415 
       
   416 				// Construct 64 bits from 8 bytes.
       
   417 				blockbits = data[0];
       
   418 				for(i = 1; i < 8; i++)
       
   419 				{
       
   420 					blockbits <<= 8;
       
   421 					blockbits |= data[i];
       
   422 				}
       
   423 
       
   424 				diffbit = (blockbits >> 33) & 1;
       
   425 				flipbit = (blockbits >> 32) & 1;
       
   426 
       
   427 				// Base color.
       
   428 
       
   429 				if(!diffbit)
       
   430 				{
       
   431 					// Individual mode.
       
   432 					
       
   433 					// Subblock 1.
       
   434 					r[0] = (blockbits >> 60) & 0xf;
       
   435 					g[0] = (blockbits >> 52) & 0xf;
       
   436 					b[0] = (blockbits >> 44) & 0xf;
       
   437 
       
   438 					r[0] |= r[0] << 4;
       
   439 					g[0] |= g[0] << 4;
       
   440 					b[0] |= b[0] << 4;
       
   441 
       
   442 					// Subblock 2.
       
   443 					r[1] = (blockbits >> 56) & 0xf;
       
   444 					g[1] = (blockbits >> 48) & 0xf;
       
   445 					b[1] = (blockbits >> 40) & 0xf;
       
   446 
       
   447 					r[1] |= r[1] << 4;
       
   448 					g[1] |= g[1] << 4;
       
   449 					b[1] |= b[1] << 4;
       
   450 				}
       
   451 				else
       
   452 				{
       
   453 					// Differential mode.
       
   454 
       
   455 					r[0] = (blockbits >> 59) & 0x1f;
       
   456 					g[0] = (blockbits >> 51) & 0x1f;
       
   457 					b[0] = (blockbits >> 43) & 0x1f;
       
   458 
       
   459 					dr = (blockbits >> 56) & 0x7;
       
   460 					dg = (blockbits >> 48) & 0x7;
       
   461 					db = (blockbits >> 40) & 0x7;
       
   462 
       
   463 					// Subblock 2.
       
   464 					r[1] = dglAddTwosComplement(r[0], dr);
       
   465 					g[1] = dglAddTwosComplement(g[0], dg);
       
   466 					b[1] = dglAddTwosComplement(b[0], db);
       
   467 
       
   468 					r[1] = (r[1] << 3) | ((r[1] >> 2) & 0x7);
       
   469 					g[1] = (g[1] << 3) | ((g[1] >> 2) & 0x7);
       
   470 					b[1] = (b[1] << 3) | ((b[1] >> 2) & 0x7);
       
   471 
       
   472 					// Subblock 1.
       
   473 					r[0] = (r[0] << 3) | ((r[0] >> 2) & 0x7);
       
   474 					g[0] = (g[0] << 3) | ((g[0] >> 2) & 0x7);
       
   475 					b[0] = (b[0] << 3) | ((b[0] >> 2) & 0x7);
       
   476 				}
       
   477 
       
   478 				// Modifier tables.
       
   479 
       
   480 				table[0] = (blockbits >> 37) & 0x7;
       
   481 				table[1] = (blockbits >> 34) & 0x7;
       
   482 
       
   483 				// Write final pixel colors in a top-down left-right order per block.
       
   484 				for(pixel = 0; pixel < 4 * 4; pixel++)
       
   485 				{
       
   486 					static const int tables[][8] = {{2, 8}, {15, 17}, {9, 29}, {13, 42},
       
   487 										 	    {18, 60}, {24, 80}, {33, 106}, {47, 183}};
       
   488 					
       
   489 					int x, y;
       
   490 					int loc;
       
   491 					int subblock;
       
   492 					int modifier;
       
   493 
       
   494 					x = 4 * xblock + pixel / 4;
       
   495 					y = 4 * yblock + pixel % 4;
       
   496 
       
   497 					if(x >= width || y >= height)
       
   498 					{
       
   499 						continue;
       
   500 					}
       
   501 
       
   502 					// Memory location of destination pixel.
       
   503 					loc = y * width + x;
       
   504 					loc *= bytes_per_pixel;
       
   505 
       
   506 					if(flipbit)
       
   507 					{
       
   508 						subblock = (pixel / 2) & 1;
       
   509 					}
       
   510 					else
       
   511 					{
       
   512 						subblock = pixel / 8;
       
   513 					}
       
   514 
       
   515 					DGLES2_ASSERT(subblock == 0 || subblock == 1);
       
   516 
       
   517 					modifier = tables[table[subblock]][(blockbits >> pixel) & 1];
       
   518 					if((blockbits >> (16 + pixel)) & 1)
       
   519 					{
       
   520 						modifier *= -1;
       
   521 					}
       
   522 
       
   523 					decompressed[loc + 0] = dglClamp(r[subblock] + modifier, 0, 255);
       
   524 					decompressed[loc + 1] = dglClamp(g[subblock] + modifier, 0, 255);
       
   525 					decompressed[loc + 2] = dglClamp(b[subblock] + modifier, 0, 255);
       
   526 				}
       
   527 
       
   528 				// Move to next block.
       
   529 				data += 8;
       
   530 			}
       
   531 		}
       
   532 	}
       
   533 
       
   534 	return decompressed;
       
   535 }
       
   536 
       
   537 static GLboolean dglIsPalettedFormat(GLenum format)
       
   538 {
       
   539 	switch(format)
       
   540 	{
       
   541 	case GL_PALETTE4_RGB8_OES:
       
   542 	case GL_PALETTE4_RGBA8_OES:
       
   543 	case GL_PALETTE4_R5_G6_B5_OES:
       
   544 	case GL_PALETTE4_RGBA4_OES:
       
   545 	case GL_PALETTE4_RGB5_A1_OES:
       
   546 	case GL_PALETTE8_RGB8_OES:
       
   547 	case GL_PALETTE8_RGBA8_OES:
       
   548 	case GL_PALETTE8_R5_G6_B5_OES:
       
   549 	case GL_PALETTE8_RGBA4_OES:
       
   550 	case GL_PALETTE8_RGB5_A1_OES:
       
   551 		return GL_TRUE;
       
   552 	default:
       
   553 		return GL_FALSE;
       
   554 	}
       
   555 }
       
   556 
       
   557 static GLenum dglMapPalettedToBaseFormat(GLenum format)
       
   558 {
       
   559 	switch(format)
       
   560 	{
       
   561 	case GL_PALETTE4_RGB8_OES:
       
   562 	case GL_PALETTE4_R5_G6_B5_OES:
       
   563 	case GL_PALETTE8_RGB8_OES:
       
   564 	case GL_PALETTE8_R5_G6_B5_OES:
       
   565 		return GL_RGB;
       
   566 
       
   567 	case GL_PALETTE4_RGBA8_OES:
       
   568 	case GL_PALETTE4_RGBA4_OES:
       
   569 	case GL_PALETTE4_RGB5_A1_OES:
       
   570 	case GL_PALETTE8_RGBA8_OES:
       
   571 	case GL_PALETTE8_RGBA4_OES:
       
   572 	case GL_PALETTE8_RGB5_A1_OES:
       
   573 		return GL_RGBA;
       
   574 	
       
   575 	default:
       
   576 		DGLES2_ASSERT(GL_FALSE);
       
   577 	}
       
   578 
       
   579 	// not reached
       
   580 	return 0;
       
   581 }
       
   582 
       
   583 static void* dglDecompressPalettedTexture(int level, GLenum format, int width, int height, int imageSize, const void* data)
       
   584 {
       
   585 	const unsigned char* palette = data;
       
   586 	int bits_per_pixel;
       
   587 	int palette_entry_size;
       
   588 	int num_palette_entries;
       
   589 	const unsigned char* image_data;
       
   590 	int i;
       
   591 	int bytes_per_pixel;
       
   592 	GLenum base_format;
       
   593 	char* decompressed_data;
       
   594 	int pixels_per_byte;
       
   595 	int max_pixels;
       
   596 	int end;
       
   597 	int r, g, b, a;
       
   598 	
       
   599 	switch(format)
       
   600 	{
       
   601 	case GL_PALETTE4_RGB8_OES:
       
   602 		bits_per_pixel = 4;
       
   603 		palette_entry_size = 3;
       
   604 		break;
       
   605 
       
   606 	case GL_PALETTE4_RGBA8_OES:
       
   607 		bits_per_pixel = 4;
       
   608 		palette_entry_size = 4;
       
   609 		break;
       
   610 
       
   611 	case GL_PALETTE4_R5_G6_B5_OES:
       
   612 	case GL_PALETTE4_RGB5_A1_OES:
       
   613 	case GL_PALETTE4_RGBA4_OES:
       
   614 		bits_per_pixel = 4;
       
   615 		palette_entry_size = 2;
       
   616 		break;
       
   617 
       
   618 	case GL_PALETTE8_RGB8_OES:
       
   619 		bits_per_pixel = 8;
       
   620 		palette_entry_size = 3;
       
   621 		break;
       
   622 
       
   623 	case GL_PALETTE8_RGBA8_OES:
       
   624 		bits_per_pixel = 8;
       
   625 		palette_entry_size = 4;
       
   626 		break;
       
   627 
       
   628 	case GL_PALETTE8_R5_G6_B5_OES:
       
   629 	case GL_PALETTE8_RGBA4_OES:
       
   630 	case GL_PALETTE8_RGB5_A1_OES:
       
   631 		bits_per_pixel = 8;
       
   632 		palette_entry_size = 2;
       
   633 		break;
       
   634 
       
   635 	default:
       
   636 		DGLES2_ASSERT(GL_FALSE);
       
   637 	}
       
   638 
       
   639 	num_palette_entries = 2 << (bits_per_pixel - 1);
       
   640 	image_data = palette + num_palette_entries * palette_entry_size;
       
   641 
       
   642 	// Skip to the correct mip level
       
   643 	for(i = 0; i < level; i++)
       
   644 	{
       
   645 		if(bits_per_pixel == 8)
       
   646 		{
       
   647 			image_data += width * height * bits_per_pixel / 8;
       
   648 		}
       
   649 		else
       
   650 		{
       
   651 			DGLES2_ASSERT(bits_per_pixel == 4);
       
   652 			image_data += width * height * bits_per_pixel / 8 / 2;
       
   653 		}
       
   654 		width /= 2;
       
   655 		height /= 2;
       
   656 	}
       
   657 
       
   658 	base_format = dglMapPalettedToBaseFormat(format);
       
   659 	if(base_format == GL_RGB)
       
   660 	{
       
   661 		bytes_per_pixel = 3;
       
   662 	}
       
   663 	else
       
   664 	{
       
   665 		DGLES2_ASSERT(base_format == GL_RGBA);
       
   666 		bytes_per_pixel = 4;
       
   667 	}
       
   668 
       
   669 	decompressed_data = malloc(width * height * bytes_per_pixel);
       
   670 	if(decompressed_data == NULL)
       
   671 	{
       
   672 		return NULL;
       
   673 	}
       
   674 	
       
   675 	// Don't go past the end of the data
       
   676 	pixels_per_byte = 8 / bits_per_pixel;
       
   677 	max_pixels = ((const unsigned char*)data + imageSize - image_data) * pixels_per_byte;
       
   678 	end = dglMin(width * height, max_pixels);
       
   679 
       
   680 	for(i = 0; i < end; i++)
       
   681 	{
       
   682 		int index;
       
   683 		if(bits_per_pixel == 4)
       
   684 		{
       
   685 			if(i & 1)
       
   686 			{
       
   687 				index = image_data[i / 2] & 15;
       
   688 			}
       
   689 			else
       
   690 			{
       
   691 				index = image_data[i / 2] >> 4;
       
   692 			}
       
   693 		}
       
   694 		else
       
   695 		{
       
   696 			DGLES2_ASSERT(bits_per_pixel == 8);
       
   697 			index = image_data[i];
       
   698 		}
       
   699 
       
   700 		switch(format)
       
   701 		{
       
   702 		case GL_PALETTE4_RGB8_OES:
       
   703 		case GL_PALETTE8_RGB8_OES:
       
   704 			r = palette[index*3];
       
   705 			g = palette[index*3+1];
       
   706 			b = palette[index*3+2];
       
   707 			break;
       
   708 
       
   709 		case GL_PALETTE4_RGBA8_OES:
       
   710 		case GL_PALETTE8_RGBA8_OES:
       
   711 			r = palette[index*4];
       
   712 			g = palette[index*4+1];
       
   713 			b = palette[index*4+2];
       
   714 			a = palette[index*4+3];
       
   715 			break;
       
   716 
       
   717 		case GL_PALETTE4_R5_G6_B5_OES:
       
   718 		case GL_PALETTE8_R5_G6_B5_OES:
       
   719 			r = palette[index*2+1] >> 3;
       
   720 			r = (r << 3) | (r >> 2);
       
   721 			g = ((palette[index*2+1] & 7) << 3) | (palette[index*2] >> 5);
       
   722 			g = (g << 2) | (g >> 4);
       
   723 			b = palette[index*2] & 0x1f;
       
   724 			b = (b << 3) | (b >> 2);
       
   725 			break;
       
   726 
       
   727 		case GL_PALETTE4_RGBA4_OES:
       
   728 		case GL_PALETTE8_RGBA4_OES:
       
   729 			r = palette[index*2+1] >> 4;
       
   730 			r |= (r << 4) | r;
       
   731 			g = palette[index*2+1] & 0xf;
       
   732 			g |= (g << 4) | g;
       
   733 			b = palette[index*2] >> 4;
       
   734 			b |= (b << 4) | b;
       
   735 			a = palette[index*2] & 0xf;
       
   736 			a |= (a << 4) | a;
       
   737 			break;
       
   738 
       
   739 		case GL_PALETTE4_RGB5_A1_OES:
       
   740 		case GL_PALETTE8_RGB5_A1_OES:
       
   741 			r = palette[index*2+1] >> 3;
       
   742 			r = (r << 3) | (r >> 2);
       
   743 			g = ((palette[index*2+1] & 7) << 2) | (palette[index*2] >> 6);
       
   744 			g = (g << 3) | (g >> 2);
       
   745 			b = (palette[index*2] >> 1) & 0x1f;
       
   746 			b = (b << 3) | (b >> 2);
       
   747 			a = (palette[index*2] & 1) ? 255 : 0;
       
   748 			break;
       
   749 			
       
   750 		default:
       
   751 			DGLES2_ASSERT(GL_FALSE);
       
   752 		}
       
   753 
       
   754 		if(base_format == GL_RGB)
       
   755 		{
       
   756 			decompressed_data[i*3+0] = r;
       
   757 			decompressed_data[i*3+1] = g;
       
   758 			decompressed_data[i*3+2] = b;
       
   759 		}
       
   760 		else
       
   761 		{
       
   762 			DGLES2_ASSERT(base_format == GL_RGBA);
       
   763 			decompressed_data[i*4+0] = r;
       
   764 			decompressed_data[i*4+1] = g;
       
   765 			decompressed_data[i*4+2] = b;
       
   766 			decompressed_data[i*4+3] = a;
       
   767 		}
       
   768 	}
       
   769 
       
   770 	return decompressed_data;
       
   771 }
       
   772 
       
   773 GL_APICALL_BUILD void GL_APIENTRY glActiveTexture(GLenum texture)
       
   774 {
       
   775 	DGLES2_ENTER();
       
   776 	ctx->hgl.ActiveTexture(texture);
       
   777 	DGLES2_LEAVE();
       
   778 }
       
   779 
       
   780 GL_APICALL_BUILD void GL_APIENTRY glBindTexture (GLenum target, GLuint texture)
       
   781 {
       
   782 	DGLES2_ENTER();
       
   783 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
   784 	DGLContext_getHostError(ctx);
       
   785 //	Dprintf("glBindTexture(%x, %d)\n", target, texture);
       
   786 	ctx->hgl.BindTexture(target, texture);
       
   787 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   788 	{
       
   789 		if(!DGLContext_bindTexture(ctx, target, texture))
       
   790 		{
       
   791 			DGLES2_ERROR(GL_OUT_OF_MEMORY);
       
   792 		}
       
   793 	}
       
   794 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   795 }
       
   796 
       
   797 static GLboolean dglIsValid2DTextureTarget(GLenum target)
       
   798 {
       
   799 	switch(target)
       
   800 	{
       
   801 		case GL_TEXTURE_2D:
       
   802 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
       
   803 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
       
   804 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
       
   805 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
       
   806 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
       
   807 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
       
   808 			return GL_TRUE;
       
   809 
       
   810 		default:
       
   811 			return GL_FALSE;
       
   812 	}
       
   813 }
       
   814 
       
   815 GL_APICALL_BUILD void GL_APIENTRY glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data)
       
   816 {
       
   817 	DGLES2_ENTER();
       
   818 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
   819 	DGLES2_ERROR_IF(!dglIsPalettedFormat(internalformat) &&
       
   820 					internalformat != GL_ETC1_RGB8_OES,
       
   821 					GL_INVALID_ENUM);
       
   822 	DGLES2_ERROR_IF(height < 0, GL_INVALID_VALUE);
       
   823 	DGLES2_ERROR_IF(width < 0, GL_INVALID_VALUE);
       
   824 	DGLES2_ERROR_IF(border != 0, GL_INVALID_VALUE);
       
   825 	DGLES2_ERROR_IF(imageSize < 0, GL_INVALID_VALUE);
       
   826 	{
       
   827 		if(dglIsPalettedFormat(internalformat))
       
   828 		{
       
   829 			int num_levels, cur_level;
       
   830 			GLenum base_format;
       
   831 			DGLTexture* texture;
       
   832 
       
   833 			base_format = dglMapPalettedToBaseFormat(internalformat);
       
   834 			texture = DGLContext_getTexture(ctx, target);
       
   835 			DGLES2_ASSERT(texture != NULL);
       
   836 
       
   837 			DGLES2_ERROR_IF(level > 0, GL_INVALID_VALUE);
       
   838 			DGLES2_ERROR_IF(level < -ctx->max_texture_level, GL_INVALID_VALUE);
       
   839 
       
   840 			num_levels = -level + 1;
       
   841 			for(cur_level = 0; cur_level < num_levels; cur_level++)
       
   842 			{
       
   843 				if(data != NULL)
       
   844 				{
       
   845 					void* decompressed_data = dglDecompressPalettedTexture(cur_level, internalformat, width, height, imageSize, data);
       
   846 					if(decompressed_data == NULL)
       
   847 					{
       
   848 						DGLES2_ERROR(GL_OUT_OF_MEMORY);
       
   849 					}
       
   850 					ctx->hgl.TexImage2D(target, cur_level, base_format, width, height, border, base_format, GL_UNSIGNED_BYTE, decompressed_data);
       
   851 					free(decompressed_data);
       
   852 				}
       
   853 				else
       
   854 				{
       
   855 					ctx->hgl.TexImage2D(target, cur_level, base_format, width, height, border, base_format, GL_UNSIGNED_BYTE, NULL);
       
   856 				}
       
   857 				if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   858 				{
       
   859 					DGLTexture_setLevel(texture, target, level, internalformat, width, height);
       
   860 					DGLTexture_setEGLImage(texture, target, NULL);
       
   861 				}
       
   862 				width /= 2;
       
   863 				height /= 2;
       
   864 			}
       
   865 		}
       
   866 		else
       
   867 		{
       
   868 			void* decompressed_data;
       
   869 			int numblocks;
       
   870 
       
   871 			DGLES2_ASSERT(internalformat == GL_ETC1_RGB8_OES);
       
   872 
       
   873 			DGLES2_ERROR_IF(level < 0, GL_INVALID_VALUE);
       
   874 			DGLES2_ERROR_IF(level > ctx->max_texture_level, GL_INVALID_VALUE);
       
   875 
       
   876 			numblocks = ((width + 3) / 4) * ((height + 3) / 4);
       
   877 
       
   878 			if(imageSize != numblocks * 8)
       
   879 			{
       
   880 				DGLES2_ERROR(GL_INVALID_VALUE);
       
   881 			}
       
   882 
       
   883 			decompressed_data = dglDecompressETCTexture(width, height, data);
       
   884 			ctx->hgl.TexImage2D(target, level, GL_RGB, width, height, border, GL_RGB, GL_UNSIGNED_BYTE, decompressed_data);
       
   885 			free(decompressed_data);
       
   886 			if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
   887 			{
       
   888 				DGLTexture* texture;
       
   889 				GLeglImageOES image;
       
   890 				
       
   891 				texture = DGLContext_getTexture(ctx, target);
       
   892 				DGLES2_ASSERT(texture != NULL);
       
   893 				DGLTexture_setLevel(texture, target, level, internalformat, width, height);
       
   894 				
       
   895 				image = DGLTexture_getEGLImage(texture, target);
       
   896 				if(image != NULL)
       
   897 				{
       
   898 					// Texture is respecified. It is no longer an EGLImage sibling.
       
   899 					deglUnregisterImageTarget(image, target, texture->obj.name);
       
   900 					DGLTexture_setEGLImage(texture, target, NULL);
       
   901 				}
       
   902 
       
   903 				{
       
   904 					DGLTextureLevel* level_obj = DGLTexture_getLevel(texture, target, level);
       
   905 					if(level_obj->bound_surface != NULL)
       
   906 					{
       
   907 						// Texture is respecified. Release the bound EGLSurface.
       
   908 						deglReleaseTexImage(level_obj->bound_surface, texture->obj.name, level);
       
   909 						level_obj->bound_surface = NULL;
       
   910 					}
       
   911 				}
       
   912 			}
       
   913 		}
       
   914 	}
       
   915 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   916 }
       
   917 
       
   918 GL_APICALL_BUILD void GL_APIENTRY glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data)
       
   919 {
       
   920 	DGLES2_ENTER();
       
   921 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
   922 	DGLES2_ERROR_IF(level < 0, GL_INVALID_VALUE);
       
   923 	DGLES2_ERROR_IF(level > ctx->max_texture_level, GL_INVALID_VALUE);
       
   924 	DGLES2_ERROR_IF(!dglIsPalettedFormat(format) && format != GL_ETC1_RGB8_OES, GL_INVALID_ENUM);
       
   925 	// No supported formats.
       
   926 	DGLES2_ERROR(GL_INVALID_OPERATION);
       
   927 	DGLES2_LEAVE();
       
   928 }
       
   929 
       
   930 static GLboolean dglIsValidFormat(GLenum format)
       
   931 {
       
   932 	switch(format)
       
   933 	{
       
   934 		case GL_ALPHA:
       
   935 		case GL_RGB:
       
   936 		case GL_RGBA:
       
   937 		case GL_LUMINANCE:
       
   938 		case GL_LUMINANCE_ALPHA:
       
   939 			return GL_TRUE;
       
   940 
       
   941 		default:
       
   942 			return GL_FALSE;
       
   943 	}
       
   944 }
       
   945 
       
   946 GL_APICALL_BUILD void GL_APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
       
   947 {
       
   948 	DGLES2_ENTER();
       
   949 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
   950 	DGLES2_ERROR_IF(level < 0, GL_INVALID_VALUE);
       
   951 	DGLES2_ERROR_IF(level > ctx->max_texture_level, GL_INVALID_VALUE);
       
   952 	DGLES2_ERROR_IF(!dglIsValidFormat(internalformat), GL_INVALID_ENUM);
       
   953 	DGLES2_ERROR_IF(border != 0, GL_INVALID_VALUE);
       
   954 	{
       
   955 		DGLContext_getHostError(ctx);
       
   956 
       
   957 		DGLES2_BEGIN_READING();
       
   958 		ctx->hgl.CopyTexImage2D(target, level, internalformat, x, y, width, height, border);	
       
   959 		DGLES2_END_READING();
       
   960 
       
   961 		if(DGLContext_getHostError(ctx) == GL_NO_ERROR) {
       
   962 			DGLTexture* texture;
       
   963 			GLeglImageOES image;
       
   964 			
       
   965 			texture = DGLContext_getTexture(ctx, target);
       
   966 			DGLES2_ASSERT(texture != NULL);
       
   967 			DGLTexture_setLevel(texture, target, level, internalformat, width, height);
       
   968 
       
   969 			image = DGLTexture_getEGLImage(texture, target);
       
   970 			if(image != NULL)
       
   971 			{
       
   972 				// Texture is respecified. It is no longer an EGLImage sibling.
       
   973 				deglUnregisterImageTarget(image, target, texture->obj.name);
       
   974 				DGLTexture_setEGLImage(texture, target, NULL);
       
   975 			}
       
   976 
       
   977 			{
       
   978 				DGLTextureLevel* level_obj = DGLTexture_getLevel(texture, target, level);
       
   979 				if(level_obj->bound_surface != NULL)
       
   980 				{
       
   981 					// Texture is respecified. Release the bound EGLSurface.
       
   982 					deglReleaseTexImage(level_obj->bound_surface, texture->obj.name, level);
       
   983 					level_obj->bound_surface = NULL;
       
   984 				}
       
   985 			}
       
   986 		}
       
   987 	}
       
   988 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
   989 }
       
   990 
       
   991 GL_APICALL_BUILD void GL_APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
       
   992 {
       
   993 	DGLES2_ENTER();
       
   994 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
   995 	{
       
   996 		DGLTextureLevel* level_obj = DGLContext_getTextureLevel(ctx, target, level);
       
   997 		DGLES2_ASSERT(level_obj != NULL);
       
   998 		if(dglIsPalettedFormat(level_obj->format) || level_obj->format == GL_ETC1_RGB8_OES)
       
   999 		{
       
  1000 			DGLES2_ERROR(GL_INVALID_OPERATION);
       
  1001 		}
       
  1002 	}
       
  1003 	DGLContext_getHostError(ctx);
       
  1004 	DGLES2_BEGIN_READING();
       
  1005 	ctx->hgl.CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
       
  1006 	DGLES2_END_READING();
       
  1007 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
  1008 	{
       
  1009 		DGLTexture* texture;
       
  1010 		GLeglImageOES image;
       
  1011 
       
  1012 		texture = DGLContext_getTexture(ctx, target);
       
  1013 		DGLES2_ASSERT(texture != NULL);
       
  1014 		image = DGLTexture_getEGLImage(texture, target);
       
  1015 		if(image != NULL)
       
  1016 		{
       
  1017 			deglUpdateImageSiblings(image, target, texture->obj.name);
       
  1018 		}
       
  1019 	}
       
  1020 	DGLES2_LEAVE();
       
  1021 }
       
  1022 
       
  1023 GL_APICALL_BUILD void GL_APIENTRY glDeleteTextures(GLsizei n, const GLuint* textures)
       
  1024 {
       
  1025 	DGLES2_ENTER();
       
  1026 	DGLContext_getHostError(ctx);
       
  1027 	ctx->hgl.DeleteTextures(n, textures);
       
  1028 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
  1029 	{
       
  1030 		int i;
       
  1031 		for(i = 0; i < n; i++)
       
  1032 		{
       
  1033 			DGLContext_destroyTexture(ctx, textures[n]);
       
  1034 		}
       
  1035 	}
       
  1036 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
  1037 }
       
  1038 
       
  1039 GL_APICALL_BUILD void GL_APIENTRY glGenerateMipmap (GLenum target)
       
  1040 {
       
  1041 	DGLES2_ENTER();
       
  1042 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1043 	DGLContext_getHostError(ctx);
       
  1044 	ctx->hgl.GenerateMipmapEXT(target);
       
  1045 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
  1046 	{
       
  1047 		DGLTexture* texture;
       
  1048 		GLeglImageOES image;
       
  1049 		
       
  1050 		texture = DGLContext_getTexture(ctx, target);
       
  1051 		DGLTexture_generateMipmap(texture);
       
  1052 		image = DGLTexture_getEGLImage(texture, target);
       
  1053 		if(image != NULL)
       
  1054 		{
       
  1055 			// Texture is respecified. It is no longer an EGLImage sibling.
       
  1056 			deglUnregisterImageTarget(image, target, texture->obj.name);
       
  1057 			DGLTexture_setEGLImage(texture, target, NULL);
       
  1058 		}
       
  1059 	}
       
  1060 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
  1061 }
       
  1062 
       
  1063 GL_APICALL_BUILD void GL_APIENTRY glGenTextures(GLsizei n, GLuint* textures)
       
  1064 {
       
  1065 	DGLES2_ENTER();
       
  1066 	ctx->hgl.GenTextures(n, textures);
       
  1067 	DGLES2_LEAVE();
       
  1068 }
       
  1069 
       
  1070 static GLboolean dglIsValidTextureParameter(GLenum pname)
       
  1071 {
       
  1072 	switch(pname)
       
  1073 	{
       
  1074 		case GL_TEXTURE_WRAP_S:
       
  1075 		case GL_TEXTURE_WRAP_T:
       
  1076 		case GL_TEXTURE_MIN_FILTER:
       
  1077 		case GL_TEXTURE_MAG_FILTER:
       
  1078 			return GL_TRUE;
       
  1079 
       
  1080 		default:
       
  1081 			return GL_FALSE;
       
  1082 	}
       
  1083 }
       
  1084 
       
  1085 GL_APICALL_BUILD void GL_APIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
       
  1086 {
       
  1087 	DGLES2_ENTER();
       
  1088 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1089 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1090 	ctx->hgl.GetTexParameterfv(target, pname, params);
       
  1091 	DGLES2_LEAVE();
       
  1092 }
       
  1093 
       
  1094 GL_APICALL_BUILD void GL_APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
       
  1095 {
       
  1096 	DGLES2_ENTER();
       
  1097 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1098 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1099 	ctx->hgl.GetTexParameteriv(target, pname, params);
       
  1100 	DGLES2_LEAVE();
       
  1101 }
       
  1102 
       
  1103 GL_APICALL_BUILD GLboolean GL_APIENTRY glIsTexture(GLuint texture)
       
  1104 {
       
  1105 	DGLES2_ENTER_RET(GL_FALSE);
       
  1106 	DGLES2_LEAVE_RET(ctx->hgl.IsTexture(texture));
       
  1107 }
       
  1108 
       
  1109 static GLfloat* dglConvertHalfTextureToFloat(GLsizei width, GLsizei height, GLenum format, const void* pixels)
       
  1110 {
       
  1111 	int components;
       
  1112 	GLfloat* conv;
       
  1113 	int i;
       
  1114 
       
  1115 	switch(format)
       
  1116 	{
       
  1117 		case GL_ALPHA:
       
  1118 		case GL_LUMINANCE:
       
  1119 			components = 1;
       
  1120 			break;
       
  1121 
       
  1122 		case GL_LUMINANCE_ALPHA:
       
  1123 			components = 2;
       
  1124 			break;
       
  1125 
       
  1126 		case GL_RGB:
       
  1127 			components = 3;
       
  1128 			break;
       
  1129 
       
  1130 		case GL_RGBA:
       
  1131 			components = 4;
       
  1132 			break;
       
  1133 
       
  1134 		default:
       
  1135 			DGLES2_ASSERT(GL_FALSE);
       
  1136 	}
       
  1137 
       
  1138 	conv = malloc(width * height * components * sizeof(GLfloat));
       
  1139 	if(conv == NULL)
       
  1140 	{
       
  1141 		return NULL;
       
  1142 	}
       
  1143 
       
  1144 	for(i = 0; i < width * height * components; i++)
       
  1145 	{
       
  1146 		conv[i] = dglConvertHalfToFloat(((GLfixed*)pixels)[i]);
       
  1147 	}
       
  1148 
       
  1149 	return conv;
       
  1150 }
       
  1151 
       
  1152 static GLboolean dglIsValidType(GLenum type)
       
  1153 {
       
  1154 	switch(type)
       
  1155 	{
       
  1156 		case GL_UNSIGNED_BYTE:
       
  1157 		case GL_UNSIGNED_SHORT_5_6_5:
       
  1158 		case GL_UNSIGNED_SHORT_4_4_4_4:
       
  1159 		case GL_UNSIGNED_SHORT_5_5_5_1:
       
  1160 			return GL_TRUE;
       
  1161 
       
  1162 		default:
       
  1163 			return GL_FALSE;
       
  1164 	}
       
  1165 }
       
  1166 
       
  1167 GL_APICALL_BUILD void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels)
       
  1168 {
       
  1169 	DGLES2_ENTER();
       
  1170 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
  1171 	DGLES2_ERROR_IF(level < 0, GL_INVALID_VALUE);
       
  1172 	DGLES2_ERROR_IF(level > ctx->max_texture_level, GL_INVALID_VALUE);
       
  1173 	DGLES2_ERROR_IF(dglIsPalettedFormat(internalformat), GL_INVALID_OPERATION);
       
  1174 	DGLES2_ERROR_IF(!dglIsValidFormat(internalformat), GL_INVALID_VALUE);
       
  1175 	DGLES2_ERROR_IF(!dglIsValidFormat(format), GL_INVALID_ENUM);
       
  1176 	DGLES2_ERROR_IF(!dglIsValidType(type), GL_INVALID_ENUM);
       
  1177 	DGLES2_ERROR_IF(border != 0, GL_INVALID_VALUE);
       
  1178 	DGLES2_ERROR_IF(format != internalformat, GL_INVALID_OPERATION);
       
  1179 	
       
  1180 	DGLContext_getHostError(ctx);
       
  1181 
       
  1182 	if(pixels != NULL && type == GL_HALF_FLOAT_OES)
       
  1183 	{
       
  1184 		GLfloat* conv = dglConvertHalfTextureToFloat(width, height, format, pixels);
       
  1185 		if(conv == NULL)
       
  1186 		{
       
  1187 			DGLES2_ERROR(GL_OUT_OF_MEMORY);
       
  1188 		}
       
  1189 		ctx->hgl.TexImage2D(target, level, internalformat, width, height, border, format, GL_FLOAT, conv);
       
  1190 		free(conv);
       
  1191 	}
       
  1192 	else
       
  1193 	{
       
  1194 		ctx->hgl.TexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
       
  1195 	}
       
  1196 
       
  1197 	if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
  1198 	{
       
  1199 		DGLTexture* texture;
       
  1200 		GLeglImageOES image;
       
  1201 		
       
  1202 		texture = DGLContext_getTexture(ctx, target);
       
  1203 		DGLES2_ASSERT(texture != NULL);
       
  1204 		DGLTexture_setLevel(texture, target, level, internalformat, width, height);
       
  1205 
       
  1206 		image = DGLTexture_getEGLImage(texture, target);
       
  1207 		if(image != NULL)
       
  1208 		{
       
  1209 			// Texture is respecified. It is no longer an EGLImage sibling.
       
  1210 			deglUnregisterImageTarget(image, target, texture->obj.name);
       
  1211 			DGLTexture_setEGLImage(texture, target, NULL);
       
  1212 		}
       
  1213 
       
  1214 		{
       
  1215 			DGLTextureLevel* level_obj = DGLTexture_getLevel(texture, target, level);
       
  1216 			if(level_obj->bound_surface != NULL)
       
  1217 			{
       
  1218 				// Texture is respecified. Release the bound EGLSurface.
       
  1219 				deglReleaseTexImage(level_obj->bound_surface, texture->obj.name, level);
       
  1220 				level_obj->bound_surface = NULL;
       
  1221 			}
       
  1222 		}
       
  1223 	}
       
  1224 
       
  1225 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
  1226 }
       
  1227 
       
  1228 GL_APICALL_BUILD void GL_APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param)
       
  1229 {
       
  1230 	DGLES2_ENTER();
       
  1231 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1232 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1233 	ctx->hgl.TexParameterf(target, pname, param);
       
  1234 	DGLES2_LEAVE();
       
  1235 }
       
  1236 
       
  1237 GL_APICALL_BUILD void GL_APIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
       
  1238 {
       
  1239 	DGLES2_ENTER();
       
  1240 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1241 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1242 	ctx->hgl.TexParameterfv(target, pname, params);
       
  1243 	DGLES2_LEAVE();
       
  1244 }
       
  1245 
       
  1246 GL_APICALL_BUILD void GL_APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
       
  1247 {
       
  1248 	DGLES2_ENTER();
       
  1249 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1250 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1251 	ctx->hgl.TexParameteri(target, pname, param);
       
  1252 	DGLES2_LEAVE();
       
  1253 }
       
  1254 
       
  1255 GL_APICALL_BUILD void GL_APIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
       
  1256 {
       
  1257 	DGLES2_ENTER();
       
  1258 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D && target != GL_TEXTURE_CUBE_MAP, GL_INVALID_ENUM);
       
  1259 	DGLES2_ERROR_IF(!dglIsValidTextureParameter(pname), GL_INVALID_ENUM);
       
  1260 	ctx->hgl.TexParameteriv(target, pname, params);
       
  1261 	DGLES2_LEAVE();
       
  1262 }
       
  1263 
       
  1264 GL_APICALL_BUILD void GL_APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels)
       
  1265 {
       
  1266 	DGLES2_ENTER();
       
  1267 	DGLES2_ERROR_IF(!dglIsValid2DTextureTarget(target), GL_INVALID_ENUM);
       
  1268 	DGLES2_ERROR_IF(level < 0, GL_INVALID_VALUE);
       
  1269 	DGLES2_ERROR_IF(level > ctx->max_texture_level, GL_INVALID_VALUE);
       
  1270 	DGLES2_ERROR_IF(!dglIsValidFormat(format), GL_INVALID_ENUM);
       
  1271 	DGLES2_ERROR_IF(!dglIsValidType(type), GL_INVALID_ENUM);
       
  1272 	{
       
  1273 		DGLTextureLevel* level_obj = DGLContext_getTextureLevel(ctx, target, level);
       
  1274 		DGLES2_ASSERT(level_obj != NULL);
       
  1275 		if(format != level_obj->format)
       
  1276 		{
       
  1277 			DGLES2_ERROR(GL_INVALID_OPERATION);
       
  1278 		}
       
  1279 
       
  1280 		DGLContext_getHostError(ctx);
       
  1281 
       
  1282 		if(pixels != NULL && type == GL_HALF_FLOAT_OES)
       
  1283 		{
       
  1284 			GLfloat* conv = dglConvertHalfTextureToFloat(width, height, format, pixels);
       
  1285 			if(conv == NULL)
       
  1286 			{
       
  1287 				DGLES2_ERROR(GL_OUT_OF_MEMORY);
       
  1288 			}
       
  1289 			ctx->hgl.TexSubImage2D(target, level, xoffset, yoffset, width, height, format, GL_FLOAT, conv);
       
  1290 			free(conv);
       
  1291 		}
       
  1292 		else
       
  1293 		{
       
  1294 			ctx->hgl.TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
       
  1295 		}
       
  1296 
       
  1297 		if(DGLContext_getHostError(ctx) == GL_NO_ERROR)
       
  1298 		{
       
  1299 			DGLTexture* texture;
       
  1300 			GLeglImageOES image;
       
  1301 			
       
  1302 			texture = DGLContext_getTexture(ctx, target);
       
  1303 			DGLES2_ASSERT(texture != NULL);
       
  1304 			image = DGLTexture_getEGLImage(texture, target);
       
  1305 			if(image != NULL)
       
  1306 			{
       
  1307 				deglUpdateImageSiblings(image, target, texture->obj.name);
       
  1308 			}
       
  1309 		}
       
  1310 	}
       
  1311 	DGLES2_LEAVE();
       
  1312 }
       
  1313 
       
  1314 GL_APICALL_BUILD void GL_APIENTRY glEGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
       
  1315 {
       
  1316 	DGLES2_ENTER();
       
  1317 	DGLES2_ERROR_IF(target != GL_TEXTURE_2D, GL_INVALID_ENUM);
       
  1318 	DGLES2_ERROR_IF(image == NULL, GL_INVALID_OPERATION);
       
  1319 	{
       
  1320 		// Clear all mipmap levels.
       
  1321 		int level;
       
  1322 		for(level = 0; level <= ctx->max_texture_level; level++)
       
  1323 		{
       
  1324 			ctx->hgl.TexImage2D(target, level, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
       
  1325 		}
       
  1326 
       
  1327 		if(!DGLContext_specifyTextureFromEGLImage(ctx, image, target))
       
  1328 		{
       
  1329 			DGLES2_ERROR(GL_INVALID_OPERATION);
       
  1330 		}
       
  1331 
       
  1332 		{
       
  1333 			DGLTexture* texture = DGLContext_getTexture(ctx, target);
       
  1334 			DGLTextureLevel* level_obj = DGLTexture_getLevel(texture, target, 0);
       
  1335 			if(level_obj->bound_surface != NULL)
       
  1336 			{
       
  1337 				// Texture is respecified. Release the bound EGLSurface.
       
  1338 				deglReleaseTexImage(level_obj->bound_surface, texture->obj.name, 0);
       
  1339 				level_obj->bound_surface = NULL;
       
  1340 			}
       
  1341 		}
       
  1342 	}
       
  1343 	DGLES2_LEAVE_NO_ERROR_CHECK();
       
  1344 }