/*******************************************************************************
**
**  gcoBUFFER_Construct
**
**  Construct a new gcoBUFFER object.
**
**  INPUT:
**
**      gcoHAL Hal
**          Pointer to a gcoHAL object.
**
**      gcoHARDWARE Hardware
**          Pointer to a gcoHARDWARE object.
**
**      gckCONTEXT Context
**          Pointer to a gckCONTEXT object.
**
**      gctSIZE_T MaxSize
**          Maximum size of buffer.
**
**  OUTPUT:
**
**      gcoBUFFER * Buffer
**          Pointer to a variable that will hold the the gcoBUFFER object
**          pointer.
*/
gceSTATUS
gcoBUFFER_Construct(
    IN gcoHAL Hal,
    IN gcoHARDWARE Hardware,
    IN gckCONTEXT Context,
    IN gctSIZE_T MaxSize,
    OUT gcoBUFFER * Buffer
    )
{
    gceSTATUS status;
    gcoBUFFER buffer = gcvNULL;
    gctUINT i = 0;
    gctPOINTER pointer = gcvNULL;

    gcmHEADER_ARG("Hal=0x%x Hardware=0x%x Context=0x%x MaxSize=%lu",
                  Hal, Hardware, Context, MaxSize);

    /* Verify the arguments. */
    gcmVERIFY_OBJECT(Hal, gcvOBJ_HAL);
    gcmVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);
    gcmDEBUG_VERIFY_ARGUMENT(Buffer != gcvNULL);

    /***************************************************************************
    ** Allocate and reset the gcoBUFFER object.
    */

    gcmONERROR(gcoOS_Allocate(
        gcvNULL, gcmSIZEOF(struct _gcoBUFFER), &pointer
        ));

    buffer = pointer;

    /* Initialize the gcoBUFFER object. */
    buffer->object.type = gcvOBJ_BUFFER;
    buffer->hal         = Hal;
    buffer->context     = Context;

    /* Maximum size of buffer. */
    buffer->size    = 0;
    buffer->maxSize = MaxSize;

    /* Zero the command buffers. */
    for (i = 0; i < gcmCOUNTOF(buffer->commandBuffers); ++i)
    {
        buffer->commandBuffers[i] = gcvNULL;
        buffer->signal[i]         = gcvNULL;
    }


    /***************************************************************************
    ** Query alignment.
    */

    gcmONERROR(gcoHARDWARE_QueryCommandBuffer(
        &buffer->info.alignment,
        &buffer->info.reservedHead,
        &buffer->info.reservedTail
        ));

    buffer->totalReserved
        = buffer->info.reservedHead
        + buffer->info.reservedTail
        + buffer->info.alignment;


    /***************************************************************************
    ** Initialize the command buffers.
    */

    for (i = 0; i < gcdCMD_BUFFERS; ++i)
    {
        /* Construct a command buffer. */
        gcmONERROR(gcoCMDBUF_Construct(
            gcvNULL,
            gcvNULL,
            buffer->maxSize,
            &buffer->info,
            &buffer->commandBuffers[i]
            ));

        /* Create the signal. */
        gcmONERROR(gcoOS_CreateSignal(
            gcvNULL, gcvFALSE, &buffer->signal[i]
            ));

        gcmTRACE_ZONE(
            gcvLEVEL_INFO, gcvZONE_SIGNAL,
            "%s(%d): buffer %d signal created 0x%08X",
            __FUNCTION__, __LINE__,
            i, buffer->signal[i]
            );

        /* Mark the buffer as available. */
        gcmONERROR(gcoOS_Signal(
            gcvNULL, buffer->signal[i], gcvTRUE\
            ));
    }

    /* Number of buffers initialized. */
    buffer->count = gcdCMD_BUFFERS;

    /* Grab the first command buffer. */
    buffer->currentCommandBuffer = gcvNULL;
    gcmONERROR(gcoBUFFER_GetCMDBUF(buffer));

    /* Return pointer to the gcoBUFFER object. */
    *Buffer = buffer;

    /* Success. */
    gcmFOOTER_ARG("*Buffer=0x%x", *Buffer);
    return gcvSTATUS_OK;

OnError:
    if (buffer != gcvNULL)
    {
        gcmVERIFY_OK(gcoBUFFER_FreeObjects(buffer));
    }

    /* Return the status. */
    gcmFOOTER();
    return status;
}
gctINT
slScanIdentifier(
	IN sloCOMPILER Compiler,
	IN gctUINT LineNo,
	IN gctUINT StringNo,
	IN gctSTRING Symbol,
	OUT slsLexToken * Token
	)
{
	gceSTATUS		status;
	gctINT			tokenType;
	sleSHADER_TYPE	shaderType;
	sltPOOL_STRING	symbolInPool;
	slsNAME *		typeName;

    gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "LineNo=%u", LineNo);
    gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "StringNo=%u", StringNo);
    gcmTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_COMPILER, "Symbol=%s", gcmOPT_STRING(Symbol));

	gcmASSERT(Token);

	gcmVERIFY_OK(sloCOMPILER_GetShaderType(Compiler, &shaderType));

	Token->lineNo	= LineNo;
	Token->stringNo	= StringNo;

	/* Check as a reserved keyword */
	tokenType = _SearchKeyword(Symbol);

	if (tokenType == T_RESERVED_KEYWORD)
	{
		Token->type = T_RESERVED_KEYWORD;

		gcmVERIFY_OK(sloCOMPILER_Report(
										Compiler,
										LineNo,
										StringNo,
										slvREPORT_ERROR,
										"reserved keyword : '%s'",
										Symbol));

		return T_RESERVED_KEYWORD;
	}
	else if (tokenType != T_NOT_KEYWORD)
	{
		Token->type = tokenType;

		switch (tokenType)
		{
		case T_CONST:				Token->u.qualifier	= slvQUALIFIER_CONST;				break;
		case T_UNIFORM:				Token->u.qualifier	= slvQUALIFIER_UNIFORM;				break;

		case T_ATTRIBUTE:
			if (shaderType != slvSHADER_TYPE_VERTEX)
			{
				gcmVERIFY_OK(sloCOMPILER_Report(
												Compiler,
												LineNo,
												StringNo,
												slvREPORT_ERROR,
												"'attribute' is only for the vertex shaders",
												Symbol));
			}

			Token->u.qualifier	= slvQUALIFIER_ATTRIBUTE;
			break;

		case T_VARYING:
			Token->u.qualifier	= (shaderType == slvSHADER_TYPE_VERTEX)?
					slvQUALIFIER_VARYING_OUT : slvQUALIFIER_VARYING_IN;
			break;

		case T_INVARIANT:
			Token->u.qualifier	= (shaderType == slvSHADER_TYPE_VERTEX)?
					slvQUALIFIER_INVARIANT_VARYING_OUT : slvQUALIFIER_INVARIANT_VARYING_IN;
			break;

		case T_IN:					Token->u.qualifier	= slvQUALIFIER_IN;					break;
		case T_OUT:					Token->u.qualifier	= slvQUALIFIER_OUT;					break;
		case T_INOUT:				Token->u.qualifier	= slvQUALIFIER_INOUT;				break;

		case T_HIGH_PRECISION:		Token->u.precision	= slvPRECISION_HIGH;				break;
		case T_MEDIUM_PRECISION:	Token->u.precision	= slvPRECISION_MEDIUM;				break;
		case T_LOW_PRECISION:		Token->u.precision	= slvPRECISION_LOW;					break;
		}

		gcmVERIFY_OK(sloCOMPILER_Dump(
									Compiler,
									slvDUMP_SCANNER,
									"<TOKEN line=\"%d\" string=\"%d\" type=\"keyword\" symbol=\"%s\" />",
									LineNo,
									StringNo,
									Symbol));

		return tokenType;
	}

	status = sloCOMPILER_AllocatePoolString(
											Compiler,
											Symbol,
											&symbolInPool);

	if (gcmIS_ERROR(status)) return T_EOF;

	if (sloCOMPILER_GetScannerState(Compiler) == slvSCANNER_NOMRAL)
	{
		/* Check as a type name */
		status = sloCOMPILER_SearchName(
										Compiler,
										symbolInPool,
										gcvTRUE,
										&typeName);

		if (status == gcvSTATUS_OK && typeName->type == slvSTRUCT_NAME)
		{
			Token->type			= T_TYPE_NAME;
			Token->u.typeName	= typeName;

			gcmVERIFY_OK(sloCOMPILER_Dump(
										Compiler,
										slvDUMP_SCANNER,
										"<TOKEN line=\"%d\" string=\"%d\" type=\"typeName\" symbol=\"%s\" />",
										LineNo,
										StringNo,
										symbolInPool));

			return T_TYPE_NAME;
		}
	}

	/* Treat as an identifier */
	Token->type			= T_IDENTIFIER;
	Token->u.identifier = symbolInPool;

	gcmVERIFY_OK(sloCOMPILER_Dump(
								Compiler,
								slvDUMP_SCANNER,
								"<TOKEN line=\"%d\" string=\"%d\" type=\"identifier\" symbol=\"%s\" />",
								LineNo,
								StringNo,
								Token->u.identifier));

	return T_IDENTIFIER;
}
static gceSTATUS
gcoBUFFER_GetCMDBUF(
    IN gcoBUFFER Buffer
    )
{
    gceSTATUS status;
    gcoCMDBUF command;
    gctSIZE_T index;
    gcePIPE_SELECT entryPipe;

    gcmHEADER_ARG("Buffer=0x%x", Buffer);

    /* Determine the next command buffer. */
    if (Buffer->currentCommandBuffer == gcvNULL)
    {
        /* First time - get the first buffer. */
        index = 0;

        /* Select 3D pipe for the first buffer. */
        entryPipe = gcvPIPE_3D;
    }
    else
    {
        /* Get current entry pipe. */
        entryPipe = Buffer->currentCommandBuffer->entryPipe;

        /* Determine the next command buffer index. */
        index = (Buffer->currentCommandBufferIndex + 1) % Buffer->count;
    }

    /* Test if command buffer is available. */
    status = gcoOS_WaitSignal(gcvNULL,
                              Buffer->signal[index],
                              0);

    if (status == gcvSTATUS_TIMEOUT)
    {
        if (Buffer->count < gcdMAX_CMD_BUFFERS)
        {
            do
            {
                if (Buffer->commandBuffers[Buffer->count] == gcvNULL)
                {
                    /* Construct a command buffer. */
                    gcmERR_BREAK(gcoCMDBUF_Construct(
                        gcvNULL,
                        gcvNULL,
                        Buffer->maxSize,
                        &Buffer->info,
                        &Buffer->commandBuffers[Buffer->count]));
                }

                if (Buffer->signal[Buffer->count] == gcvNULL)
                {
                    /* Create the signal. */
                    gcmERR_BREAK(gcoOS_CreateSignal(
                        gcvNULL,
                        gcvFALSE,
                        &Buffer->signal[Buffer->count]));

                    gcmTRACE_ZONE(
                        gcvLEVEL_INFO, gcvZONE_SIGNAL,
                        "%s(%d): buffer %d signal created 0x%08X",
                        __FUNCTION__, __LINE__,
                        Buffer->count, Buffer->signal[Buffer->count]);
                }

                /* Mark the buffer as available. */
                gcmERR_BREAK(gcoOS_Signal(gcvNULL,
                                          Buffer->signal[Buffer->count],
                                          gcvTRUE));

                /* Use the new buffer. */
                index          = Buffer->count;
                Buffer->count += 1;

                gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_BUFFER,
                              "Using %lu command buffers.",
                              Buffer->count);
            }
            while (gcvFALSE);
        }

        /* Wait for buffer to become available. */
        gcmONERROR(gcoOS_WaitSignal(gcvNULL,
                                    Buffer->signal[index],
                                    gcPLS.hal->timeOut));
    }
    else
    {
        gcmONERROR(status);
    }

    /* Select new command buffer. */
    Buffer->currentCommandBufferIndex = index;
    Buffer->currentCommandBuffer      = Buffer->commandBuffers[index];

    /* Grab pointer to current command buffer. */
    command = Buffer->currentCommandBuffer;

    /* Set the entry pipe. */
    command->entryPipe = entryPipe;

    /* Reset command buffer. */
    command->startOffset = 0;
    command->offset      = Buffer->info.reservedHead;
    command->free        = command->bytes - Buffer->totalReserved;

    /* Succees. */
    gcmFOOTER_ARG("currentCommandBufferIndex=%d",
                  Buffer->currentCommandBufferIndex);
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmFOOTER();
    return status;
}
Exemplo n.º 4
0
VEGLThreadData
veglGetThreadData(
    void
    )
{
    gcsTLS_PTR tls = gcvNULL;
    gceSTATUS status;
#if gcdENABLE_VG
    gctINT32 i;
#endif
    gcmHEADER();

    gcmONERROR(gcoOS_GetTLS(&tls));

    if (tls->context == gcvNULL)
    {
        gctPOINTER pointer = gcvNULL;
        VEGLThreadData thread;

        gcmONERROR(gcoOS_Allocate(
            gcvNULL, gcmSIZEOF(struct eglThreadData), &pointer
            ));

        gcmONERROR(gcoOS_ZeroMemory(
            pointer, gcmSIZEOF(struct eglThreadData)
            ));

        /* Initialize TLS record. */
        tls->context    = pointer;
        tls->destructor = _DestroyThreadData;

        /* Cast the pointer. */
        thread = (VEGLThreadData) pointer;

        /* Initialize the thread data. */
        thread->error             = EGL_SUCCESS;
        thread->api               = EGL_OPENGL_ES_API;
        thread->lastClient        = 1;
		thread->worker = gcvNULL;

        tls->currentType           = gcvHARDWARE_3D;
#if veglUSE_HAL_DUMP
        /* Get the gcoDUMP object. */
        gcmONERROR(gcoHAL_GetDump(thread->hal, &thread->dump));
#endif

#if gcdENABLE_VG
        gcmONERROR(gcoHAL_QueryChipCount(gcvNULL, &thread->chipCount));

        for (i = 0; i < thread->chipCount; i++)
        {
            gcmONERROR(gcoHAL_QueryChipLimits(gcvNULL, i, &thread->chipLimits[i]));
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            thread->maxWidth =
                gcmMAX(thread->maxWidth, (gctINT32)thread->chipLimits[i].maxWidth);

            thread->maxHeight =
                gcmMAX(thread->maxHeight, (gctINT32)thread->chipLimits[i].maxHeight);

            thread->maxSamples =
                gcmMAX(thread->maxSamples, (gctINT32)thread->chipLimits[i].maxSamples);
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            /* Query VAA support. */
            if (gcoHAL_QueryChipFeature(gcvNULL, i, gcvFEATURE_VAA))
            {
                thread->vaa = gcvTRUE;
                break;
            }
        }

        for (i = 0; i < thread->chipCount; i++)
        {
            if (gcoHAL_QueryChipFeature(gcvNULL, i, gcvFEATURE_PIPE_VG))
            {
                thread->openVGpipe = _IsHWVGDriverAvailable(thread);
                break;
            }
        }
#else
        /* Query the hardware identity. */
        gcmONERROR(gcoHAL_QueryChipIdentity(
            gcvNULL,
            &thread->chipModel,
            gcvNULL, gcvNULL, gcvNULL
            ));

        /* Query the hardware capabilities. */
        gcmONERROR(gcoHAL_QueryTargetCaps(
            gcvNULL,
            (gctUINT32_PTR) &thread->maxWidth,
            (gctUINT32_PTR) &thread->maxHeight,
            gcvNULL,
            (gctUINT32_PTR) &thread->maxSamples
            ));

        /* Query VAA support. */
        thread->vaa
            =  gcoHAL_IsFeatureAvailable(gcvNULL, gcvFEATURE_VAA)
            == gcvSTATUS_TRUE;

        /* Query OpenVG pipe support. */
        thread->openVGpipe
            =  gcoHAL_IsFeatureAvailable(gcvNULL, gcvFEATURE_PIPE_VG)
            == gcvSTATUS_TRUE;
#endif

        gcmTRACE_ZONE(
            gcvLEVEL_VERBOSE, gcdZONE_EGL_API,
            "%s(%d): maxWidth=%d maxHeight=%d maxSamples=%d vaa=%d openVG=%d",
            __FUNCTION__, __LINE__,
            thread->maxWidth, thread->maxHeight, thread->maxSamples,
            thread->vaa, thread->openVGpipe
            );
    }
Exemplo n.º 5
0
/*******************************************************************************
**
**  _WorkaroundForFilterBlit
**
**  Workaround for the dirty region issue of filter blit.
**  It only exists for old GC300 before 2.0.2 (included).
**
**  INPUT:
**
**      gctHAL Hal
**          Pointer to HAL.
**
**  OUTPUT:
**
**      Nothing.
*/
static gceSTATUS
_WorkaroundForFilterBlit(
    IN gcoHAL Hal
    )
{
    gceSTATUS status;

    gcoSURF    srcSurf = gcvNULL;
    gcsRECT    srcRect;

    gcoSURF    dstSurf = gcvNULL;
    gcsRECT    dstRect;

    do
    {
        gcmERR_BREAK(gcoSURF_Construct(
            gcvNULL,
            256,
            256,
            1,
            gcvSURF_BITMAP,
            gcvSURF_A8R8G8B8,
            gcvPOOL_DEFAULT,
            &srcSurf
            ));

        gcmERR_BREAK(gcoSURF_Construct(
            gcvNULL,
            256,
            256,
            1,
            gcvSURF_BITMAP,
            gcvSURF_A8R8G8B8,
            gcvPOOL_DEFAULT,
            &dstSurf
            ));

        srcRect.left   = 0;
        srcRect.top    = 0;
        srcRect.right  = 64;
        srcRect.bottom = 16;

        dstRect.left   = 0;
        dstRect.top    = 0;
        dstRect.right  = 128;
        dstRect.bottom = 32;

        gcmERR_BREAK(gcoSURF_FilterBlit(
            srcSurf,
            dstSurf,
            &srcRect,
            &dstRect,
            gcvNULL
            ));

        gcmERR_BREAK(gcoSURF_Destroy(srcSurf));
        srcSurf = gcvNULL;

        gcmERR_BREAK(gcoSURF_Destroy(dstSurf));
        dstSurf = gcvNULL;
    }
    while(gcvFALSE);

    if (gcmIS_ERROR(status)) {
        gcmTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_HAL,
            "Failed to workarond for GC300.");

        if (srcSurf)
        {
            gcmVERIFY_OK(gcoSURF_Destroy(srcSurf));
        }

        if (dstSurf)
        {
            gcmVERIFY_OK(gcoSURF_Destroy(dstSurf));
        }
    }

    return status;
}
Exemplo n.º 6
0
/*******************************************************************************
**
**  gcoHAL_Construct
**
**  Construct a new gcoHAL object.
**
**  INPUT:
**
**      gctPOINTER Context
**          Pointer to a context that can be used by the platform specific
**          functions.
**
**      gcoOS Os
**          Pointer to an gcoOS object.
**
**  OUTPUT:
**
**      gcoHAL * Hal
**          Pointer to a variable that will hold the gcoHAL object pointer.
*/
gceSTATUS
gcoHAL_Construct(
    IN gctPOINTER Context,
    IN gcoOS Os,
    OUT gcoHAL * Hal
    )
{
    gctBOOL created = gcvFALSE;
    gcoHAL hal = gcPLS.hal;
    gceSTATUS status;
    gctPOINTER pointer = gcvNULL;
    gctBOOL separated3D = gcvFALSE;
    gctBOOL separated2D = gcvFALSE;
    gcsHAL_INTERFACE iface;
    gctINT32 i;

    gcmHEADER_ARG("Context=0x%x OS=0x%x", Context, Os);

    /* Verify the arguments. */
    gcmDEBUG_VERIFY_ARGUMENT(Hal != gcvNULL);

    if (hal == gcvNULL)
    {
        /* Create the gcoHAL object. */
        gcmONERROR(gcoOS_Allocate(gcvNULL,
                                  gcmSIZEOF(struct _gcoHAL),
                                  &pointer));
        hal     = pointer;
        created = gcvTRUE;

        gcoOS_ZeroMemory(hal, gcmSIZEOF(struct _gcoHAL));

        /* Initialize the object. */
        hal->object.type = gcvOBJ_HAL;

        /* Zero the gco2D, gco3D, and gcoDUMP objects. */
        hal->dump      = gcvNULL;
        hal->reference = gcvNULL;

        /* Initialize timeOut value */
        hal->timeOut     = gcdGPU_TIMEOUT;

        /* Query the kernel version number. */
        iface.command = gcvHAL_VERSION;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        /* Test if versions match. */
        if ((iface.u.Version.major != gcvVERSION_MAJOR)
        ||  (iface.u.Version.minor != gcvVERSION_MINOR)
        ||  (iface.u.Version.patch != gcvVERSION_PATCH)
        ||  (iface.u.Version.build != gcvVERSION_BUILD)
        )
        {
            gcmPRINT("HAL user version %d.%d.%d build %u %s %s",
                     gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                     gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
            gcmPRINT("HAL kernel version %d.%d.%d build %u",
                     iface.u.Version.major, iface.u.Version.minor,
                     iface.u.Version.patch, iface.u.Version.build);

            gcmONERROR(gcvSTATUS_VERSION_MISMATCH);
        }

#if gcmIS_DEBUG(gcdDEBUG_TRACE)
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL user version %d.%d.%d build %u %s %s",
                  gcvVERSION_MAJOR, gcvVERSION_MINOR, gcvVERSION_PATCH,
                  gcvVERSION_BUILD, gcvVERSION_DATE, gcvVERSION_TIME);
    gcmTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HAL,
                  "HAL kernel version %d.%d.%d build %u",
                  iface.u.Version.major, iface.u.Version.minor,
                  iface.u.Version.patch, iface.u.Version.build);
#endif

        /* Query chip info */
        iface.command = gcvHAL_CHIP_INFO;
        gcmONERROR(gcoOS_DeviceControl(gcvNULL,
                                       IOCTL_GCHAL_INTERFACE,
                                       &iface, gcmSIZEOF(iface),
                                       &iface, gcmSIZEOF(iface)));

        hal->chipCount = iface.u.ChipInfo.count;

        for (i = 0; i < hal->chipCount; i++)
        {
            hal->chipTypes[i] = iface.u.ChipInfo.types[i];

            switch (hal->chipTypes[i])
            {
            case gcvHARDWARE_3D:
                separated3D = gcvTRUE;
                break;
            case gcvHARDWARE_2D:
                separated2D = gcvTRUE;
                break;
            default:
                break;
            }
        }

        hal->separated3D2D = (separated3D && separated2D);

#if VIVANTE_PROFILER
        hal->profiler.enable = 0;
#endif

        /* Create reference. */
        gcmONERROR(gcoOS_AtomConstruct(Os, &hal->reference));
    }
Exemplo n.º 7
0
EGLAPI EGLBoolean EGLAPIENTRY
eglChooseConfig(
    EGLDisplay Dpy,
    const EGLint *attrib_list,
    EGLConfig *configs,
    EGLint config_size,
    EGLint *num_config
    )
{
    VEGLThreadData thread;
    VEGLDisplay dpy;
    struct eglConfig criteria = { 0 };
    EGLint config;

    gcmHEADER_ARG("Dpy=0x%x attrib_list=0x%x configs=0x%x config_size=%d",
                  Dpy, attrib_list, configs, config_size);

    /* Get thread data. */
    thread = veglGetThreadData();
    if (thread == gcvNULL)
    {
        gcmTRACE(
            gcvLEVEL_ERROR,
            "%s(%d): veglGetThreadData failed.",
            __FUNCTION__, __LINE__
            );

        gcmFOOTER_ARG("return=%d", EGL_FALSE);
        return EGL_FALSE;
    }

    /* Create a shortcut to the display. */
    dpy = VEGL_DISPLAY(Dpy);

    /* Test for valid EGLDisplay structure. */
    if ((dpy == gcvNULL)
    ||  (dpy->signature != EGL_DISPLAY_SIGNATURE)
    )
    {
        /* Bad display. */
        thread->error = EGL_BAD_DISPLAY;
        gcmFOOTER_ARG("return=%d", EGL_FALSE);
        return EGL_FALSE;
    }

    if (num_config == gcvNULL)
    {
        /* Bad parameter. */
        thread->error = EGL_BAD_PARAMETER;
        gcmFOOTER_ARG("return=%d", EGL_FALSE);
        return EGL_FALSE;
    }

    /* Parse attributes. */
    if (!veglParseAttributes(dpy, attrib_list, &criteria))
    {
        /* Bail out on invalid or non-matching attributes. */
        gcmFOOTER_ARG("return=%d", EGL_FALSE);
        return EGL_FALSE;
    }

    /* Reference the EGLDisplay. */
    if (!veglReferenceDisplay(thread, dpy))
    {
        /* Not initialized. */
        thread->error = EGL_NOT_INITIALIZED;
        gcmFOOTER_ARG("return=%d", EGL_FALSE);
        return EGL_FALSE;
    }

    /* Reset number of configurations. */
    *num_config = 0;

    /* Walk through all configurations. */
    for (config = 0; config < dpy->configCount; config++)
    {
        /* Get pointer to configuration. */
        VEGLConfig configuration = &dpy->config[config];

        gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                      "%s: examining config index=%d",
                      __FUNCTION__, config);

		if (criteria.configId != EGL_DONT_CARE)
        {
            if (!((criteria.configId == configuration->configId) ||
                ((criteria.configId == 0) && configuration->defaultConfig)))
            {
                /* Criterium doesn't match. */
                gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                    "  rejected on config ID.");
                continue;
            }
            else
            {
                *num_config += 1;

                if (configs != gcvNULL)
                {
                    /* Copy configuration into specified buffer. */
                    *configs = configuration;
                }

                break;
            }
        }

        /* Check configuration against criteria. */
        if (criteria.bufferSize > configuration->bufferSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on buffer size.");
            continue;
        }

        if (criteria.alphaSize > configuration->alphaSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on alpha size.");
            continue;
        }

        if (criteria.blueSize > configuration->blueSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on blue size.");
            continue;
        }

        if (criteria.greenSize > configuration->greenSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on green size.");
            continue;
        }

        if (criteria.redSize > configuration->redSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on red size.");
            continue;
        }

        if (criteria.depthSize > configuration->depthSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on depth size.");
            continue;
        }

        if (criteria.stencilSize > configuration->stencilSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on stencil size.");
            continue;
        }

        if ((criteria.configCaveat != (EGLenum) EGL_DONT_CARE)
        &&  (criteria.configCaveat != configuration->configCaveat)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on config caveat.");
            continue;
        }

        if ((criteria.configId != EGL_DONT_CARE) &&
            !((criteria.configId == configuration->configId) ||
              ((criteria.configId == 0) && configuration->defaultConfig)))
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on config ID.");
            continue;
        }

        if ((criteria.nativeRenderable != (EGLBoolean) EGL_DONT_CARE)
        &&  criteria.nativeRenderable
        &&  (criteria.nativeRenderable != configuration->nativeRenderable)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on native renderable.");
            continue;
        }

        if ((criteria.nativeVisualType != EGL_DONT_CARE) &&
            (criteria.nativeVisualType != configuration->nativeVisualType))
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on native visual type.");
            continue;
        }

        if (criteria.samples > configuration->samples)
        {
            if ((criteria.samples == 1) && (configuration->samples == 0))
            {
                /* Criterium still matches. */
            }
            else
            {
                /* Criterium doesn't match. */
                gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                              "  rejected on samples.");
                continue;
            }
        }

        if (criteria.sampleBuffers > configuration->sampleBuffers)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on sample buffers.");
            continue;
        }

        if ((criteria.surfaceType != (EGLenum) EGL_DONT_CARE)
        &&  !(criteria.surfaceType & configuration->surfaceType)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on surface type.");
            continue;
        }

        if ((criteria.bindToTetxureRGB != (EGLBoolean) EGL_DONT_CARE)
        &&  (criteria.bindToTetxureRGB != configuration->bindToTetxureRGB)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on bind to tetxure RGB.");
            continue;
        }

        if ((criteria.bindToTetxureRGBA != (EGLBoolean) EGL_DONT_CARE)
        &&  (criteria.bindToTetxureRGBA != configuration->bindToTetxureRGBA)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on bind to tetxure RGBA.");
            continue;
        }

        if (criteria.luminanceSize > configuration->luminanceSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on luminance size.");
            continue;
        }

        if (criteria.alphaMaskSize > configuration->alphaMaskSize)
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on alpha mask size.");
            continue;
        }

        if ((criteria.colorBufferType != (EGLenum) EGL_DONT_CARE)
        &&  (criteria.colorBufferType != configuration->colorBufferType)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on color buffer type.");
            continue;
        }

        if ((criteria.renderableType != (EGLenum) EGL_DONT_CARE)
        &&  ((criteria.renderableType & configuration->renderableType)
             != criteria.renderableType)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on renderable type.");
            continue;
        }

        if ((criteria.conformant != (EGLenum) EGL_DONT_CARE)
        &&  (criteria.conformant != 0)
        &&  !(criteria.conformant & configuration->conformant)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on conformant.");
            continue;
        }

        if ((criteria.matchNativePixmap != EGL_DONT_CARE)
        &&  (criteria.matchNativePixmap != EGL_NONE)
        )
        {
            EGLBoolean bMatch = EGL_TRUE;
            gctUINT width, height;
            gceSURF_FORMAT format = gcvSURF_UNKNOWN;
            gctUINT bitsPerPixel;

            if (!(configuration->surfaceType & EGL_PIXMAP_BIT)
            ||  !veglGetPixmapInfo(dpy->hdc,
                                   (NativePixmapType)
                                   gcmINT2PTR(criteria.matchNativePixmap),
                                   &width, &height,
                                   &bitsPerPixel,
                                   &format)
            )
            {
                /* surface type of config is not EGL_PIXMAP_BIT or bad pixmap. */
                gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                              "  rejected on match native pixmap.");
                continue;
            }

            switch (format)
            {
            case gcvSURF_R5G6B5:
                if ((configuration->redSize   != 5)
                ||  (configuration->greenSize != 6)
                ||  (configuration->blueSize  != 5)
                )
                {
                    bMatch = EGL_FALSE;
                }
                break;

            case gcvSURF_X8R8G8B8:
                if ((configuration->redSize   != 8)
                ||  (configuration->greenSize != 8)
                ||  (configuration->blueSize  != 8)
                ||  (configuration->alphaSize != 0)
                )
                {
                    bMatch = EGL_FALSE;
                }
                break;

            default:
                break;
            }

            if (!bMatch)
            {
                /* Criterium doesn't match. */
                gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                              "  rejected on match native pixmap.");
                continue;
            }
        }

        if ((criteria.matchFormat != (EGLenum) EGL_DONT_CARE)
        &&  (criteria.matchFormat != (EGLenum) EGL_NONE)
        )
        {
            EGLBoolean bMatch = EGL_TRUE;

            switch(criteria.matchFormat)
            {
            case EGL_FORMAT_RGB_565_EXACT_KHR:
                if (configuration->matchFormat != EGL_FORMAT_RGB_565_EXACT_KHR)
                {
                    bMatch = EGL_FALSE;
                }
                break;

            case EGL_FORMAT_RGB_565_KHR:
                if ((configuration->matchFormat != EGL_FORMAT_RGB_565_EXACT_KHR)
                &&  (configuration->matchFormat != EGL_FORMAT_RGB_565_KHR)
                )
                {
                    bMatch = EGL_FALSE;
                }
                break;

            case EGL_FORMAT_RGBA_8888_EXACT_KHR:
                if (configuration->matchFormat != EGL_FORMAT_RGBA_8888_EXACT_KHR)
                {
                    bMatch = EGL_FALSE;
                }
                break;

            case EGL_FORMAT_RGBA_8888_KHR:
                if ((configuration->matchFormat != EGL_FORMAT_RGBA_8888_EXACT_KHR)
                &&  (configuration->matchFormat != EGL_FORMAT_RGBA_8888_KHR)
                )
                {
                    bMatch = EGL_FALSE;
                }
                break;

            default:
                break;
            }

            if (!bMatch)
            {
                /* Criterium doesn't match. */
                gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                              "  rejected on conformant.");
                continue;
            }
        }

        if ((criteria.recordableConfig != (EGLBoolean) EGL_DONT_CARE)
        &&  (criteria.recordableConfig != configuration->recordableConfig)
        )
        {
            /* Criterium doesn't match. */
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "  rejected on recordable config.");
            continue;
        }

        gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG, "  accepted.");

        if (configs != gcvNULL)
        {
            /* Copy configuration into specified buffer. */
            configs[*num_config] = configuration;
        }

        *num_config += 1;

        if (*num_config == config_size)
        {
            /* Bail out if the specified buffer is full. */
            break;
        }
    }

    if ((*num_config > 1) && (configs != gcvNULL))
    {
        /* Sort the matching configurations. */
        veglSort((VEGLConfig *) configs, *num_config, &criteria);
    }

    /* Dereference the EGLDisplay. */
    veglDereferenceDisplay(thread, dpy, EGL_FALSE);

    /* Success. */
    thread->error = EGL_SUCCESS;
    gcmDUMP_API("${EGL eglChooseConfig 0x%08X (0x%08X) (0x%08X) 0x%08X "
                "(0x%08X)",
                Dpy, attrib_list, configs, config_size, num_config);
    gcmDUMP_API_ARRAY_TOKEN(attrib_list, EGL_NONE);
    gcmDUMP_API_ARRAY(configs, *num_config);
    gcmDUMP_API_ARRAY(num_config, 1);
    gcmDUMP_API("$}");
    gcmFOOTER_ARG("*num_config=%d", *num_config);
    return EGL_TRUE;
}
Exemplo n.º 8
0
static EGLBoolean
veglParseAttributes(
    VEGLDisplay Display,
    const EGLint * AttributeList,
    VEGLConfig Configuration
    )
{
    VEGLThreadData thread;
    EGLenum attribute;
    EGLint value = 0;

    /* Get thread data. */
    thread = veglGetThreadData();
    if (thread == gcvNULL)
    {
        gcmTRACE(
            gcvLEVEL_ERROR,
            "%s(%d): veglGetThreadData failed.",
            __FUNCTION__, __LINE__
            );

        return EGL_FALSE;
    }

    /* Assume success. */
    thread->error = EGL_SUCCESS;

    /* Fill in default attributes. */
    Configuration->bufferSize        = 0;
    Configuration->alphaSize         = 0;
    Configuration->blueSize          = 0;
    Configuration->greenSize         = 0;
    Configuration->redSize           = 0;
    Configuration->depthSize         = 0;
    Configuration->stencilSize       = 0;
    Configuration->configCaveat      = (EGLenum) EGL_DONT_CARE;
    Configuration->configId          = EGL_DONT_CARE;
    Configuration->nativeRenderable  = (EGLBoolean) EGL_DONT_CARE;
    Configuration->nativeVisualType  = EGL_DONT_CARE;
    Configuration->samples           = 0;
    Configuration->sampleBuffers     = 0;
    Configuration->surfaceType       = EGL_WINDOW_BIT;
    Configuration->bindToTetxureRGB  = (EGLBoolean) EGL_DONT_CARE;
    Configuration->bindToTetxureRGBA = (EGLBoolean) EGL_DONT_CARE;
    Configuration->luminanceSize     = 0;
    Configuration->alphaMaskSize     = 0;
    Configuration->colorBufferType   = EGL_RGB_BUFFER;
    Configuration->renderableType    = EGL_OPENGL_ES_BIT;
    Configuration->conformant        = 0;
    Configuration->matchFormat       = (EGLenum) EGL_DONT_CARE;
    Configuration->matchNativePixmap = EGL_NONE;
    Configuration->recordableConfig  = (EGLBoolean) EGL_DONT_CARE;

    /* Parse the attribute list. */
    do
    {
        if (AttributeList != gcvNULL)
        {
            attribute      = AttributeList[0];
            value          = AttributeList[1];
            AttributeList += 2;
        }
        else
        {
            attribute = EGL_NONE;
        }

        switch (attribute)
        {
        case EGL_BUFFER_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                         "%s: EGL_BUFFER_SIZE=%d",
                         __FUNCTION__, value);
            Configuration->bufferSize = value;
            break;

        case EGL_ALPHA_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                         "%s: EGL_ALPHA_SIZE=%d",
                         __FUNCTION__, value);
            Configuration->alphaSize = value;
            break;

        case EGL_BLUE_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_BLUE_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->blueSize = value;
            break;

        case EGL_GREEN_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_GREEN_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->greenSize = value;
            break;

        case EGL_RED_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_RED_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->redSize = value;
            break;

        case EGL_DEPTH_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_DEPTH_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->depthSize = value;
            break;

        case EGL_STENCIL_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_STENCIL_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->stencilSize = value;
            break;

        case EGL_CONFIG_CAVEAT:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_CONFIG_CAVEAT=%d",
                          __FUNCTION__, value);
            Configuration->configCaveat = value;
            break;

        case EGL_CONFIG_ID:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_CONFIG_ID=%d",
                          __FUNCTION__, value);
            Configuration->configId = value;
            break;

        case EGL_LEVEL:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_LEVEL=%d",
                          __FUNCTION__, value);
            if ((value != EGL_DONT_CARE) && (value != 0))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_MAX_PBUFFER_WIDTH:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MAX_PBUFFER_WIDTH=%d",
                          __FUNCTION__, value);
            if ((value != EGL_DONT_CARE) && (value > thread->maxWidth))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_MAX_PBUFFER_HEIGHT:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MAX_PBUFFER_HEIGHT=%d",
                          __FUNCTION__, value);
            if ((value != EGL_DONT_CARE) && (value > thread->maxHeight))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_MAX_PBUFFER_PIXELS:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MAX_PBUFFER_PIXELS=%d",
                          __FUNCTION__, value);
            if ( (value != EGL_DONT_CARE) &&
                 (value > thread->maxWidth * thread->maxHeight) )
            {
                return EGL_FALSE;
            }
            break;

        case EGL_NATIVE_RENDERABLE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_NATIVE_RENDERABLE=%d",
                          __FUNCTION__, value);
            Configuration->nativeRenderable = value;
            break;

        case EGL_NATIVE_VISUAL_ID:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_NATIVE_VISUAL_ID=%d",
                          __FUNCTION__, value);
            if
            (
                (value != EGL_DONT_CARE)
                &&
                (gcmINT2PTR(value) != (void*) Display->hdc)
            )
            {
                return EGL_FALSE;
            }
            break;

        case EGL_NATIVE_VISUAL_TYPE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_NATIVE_VISUAL_TYPE=%d",
                          __FUNCTION__, value);
            Configuration->nativeVisualType = value;
            break;

        case EGL_SAMPLES:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_SAMPLES=%d",
                          __FUNCTION__, value);
            Configuration->samples = value;
            break;

        case EGL_SAMPLE_BUFFERS:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_SAMPLE_BUFFERS=%d",
                          __FUNCTION__, value);
            Configuration->sampleBuffers = value;
            break;

        case EGL_SURFACE_TYPE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_SURFACE_TYPE=%d",
                          __FUNCTION__, value);
            Configuration->surfaceType = value;
            break;

        case EGL_TRANSPARENT_TYPE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_TRANSPARENT_TYPE=%d",
                          __FUNCTION__, value);
            if ((value != EGL_NONE) && (value != EGL_DONT_CARE))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_TRANSPARENT_BLUE_VALUE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_TRANSPARENT_BLUE_VALUE=%d",
                          __FUNCTION__, value);
            if (value != EGL_DONT_CARE)
            {
                return EGL_FALSE;
            }
            break;

        case EGL_TRANSPARENT_GREEN_VALUE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_TRANSPARENT_GREEN_VALUE=%d",
                          __FUNCTION__, value);
            if (value != EGL_DONT_CARE)
            {
                return EGL_FALSE;
            }
            break;

        case EGL_TRANSPARENT_RED_VALUE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_TRANSPARENT_RED_VALUE=%d",
                          __FUNCTION__, value);
            if (value != EGL_DONT_CARE)
            {
                return EGL_FALSE;
            }
            break;

        case EGL_BIND_TO_TEXTURE_RGB:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_BIND_TO_TEXTURE_RGB=%d",
                          __FUNCTION__, value);
            Configuration->bindToTetxureRGB = value;
            break;

        case EGL_BIND_TO_TEXTURE_RGBA:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_BIND_TO_TEXTURE_RGBA=%d",
                          __FUNCTION__, value);
            Configuration->bindToTetxureRGBA = value;
            break;

        case EGL_MIN_SWAP_INTERVAL:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MIN_SWAP_INTERVAL=%d",
                          __FUNCTION__, value);
            if ((value != EGL_DONT_CARE) && (value > 1))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_MAX_SWAP_INTERVAL:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MAX_SWAP_INTERVAL=%d",
                          __FUNCTION__, value);
            if ((value != EGL_DONT_CARE) && (value > 1))
            {
                return EGL_FALSE;
            }
            break;

        case EGL_LUMINANCE_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_LUMINANCE_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->luminanceSize = value;
            break;

        case EGL_ALPHA_MASK_SIZE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_ALPHA_MASK_SIZE=%d",
                          __FUNCTION__, value);
            Configuration->alphaMaskSize = value;
            break;

        case EGL_COLOR_BUFFER_TYPE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_COLOR_BUFFER_TYPE=%d",
                          __FUNCTION__, value);
            Configuration->colorBufferType = value;
            break;

        case EGL_RENDERABLE_TYPE:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_RENDERABLE_TYPE=%d",
                          __FUNCTION__, value);
            Configuration->renderableType = value;
            break;

        case EGL_CONFORMANT:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_RENDERABLE_TYPE=%d",
                          __FUNCTION__, value);
            Configuration->conformant = value;
            break;

        case EGL_MATCH_FORMAT_KHR:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MATCH_FORMAT_KHR=%d",
                          __FUNCTION__, value);
            Configuration->matchFormat = value;
            break;

        case EGL_MATCH_NATIVE_PIXMAP:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_MATCH_NATIVE_PIXMAP=%d",
                          __FUNCTION__, value);
            Configuration->matchNativePixmap = value;
            break;

        case EGL_RECORDABLE_ANDROID:
            gcmTRACE_ZONE(gcvLEVEL_INFO, gcdZONE_EGL_CONFIG,
                          "%s: EGL_RECORDABLE_ANDROID=%d",
                          __FUNCTION__, value);
            Configuration->recordableConfig = value;
            break;

        case EGL_NONE:
            break;

        default:
            /* Bad attribute. */
            thread->error = EGL_BAD_ATTRIBUTE;
            return EGL_FALSE;
        }
    }
    while (attribute != EGL_NONE);

    /* Success. */
    return EGL_TRUE;
}