/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief EGL config dst->
 *//*--------------------------------------------------------------------*/

#include "egluConfigInfo.hpp"
#include "egluDefs.hpp"
#include "eglwLibrary.hpp"
#include "eglwEnums.hpp"
#include "egluUtil.hpp"
#include "deSTLUtil.hpp"

namespace eglu
{

using namespace eglw;

deInt32 ConfigInfo::getAttribute (deUint32 attribute) const
{
	switch (attribute)
	{
		case EGL_BUFFER_SIZE:				return bufferSize;
		case EGL_RED_SIZE:					return redSize;
		case EGL_GREEN_SIZE:				return greenSize;
		case EGL_BLUE_SIZE:					return blueSize;
		case EGL_LUMINANCE_SIZE:			return luminanceSize;
		case EGL_ALPHA_SIZE:				return alphaSize;
		case EGL_ALPHA_MASK_SIZE:			return alphaMaskSize;
		case EGL_BIND_TO_TEXTURE_RGB:		return bindToTextureRGB;
		case EGL_BIND_TO_TEXTURE_RGBA:		return bindToTextureRGBA;
		case EGL_COLOR_BUFFER_TYPE:			return colorBufferType;
		case EGL_CONFIG_CAVEAT:				return configCaveat;
		case EGL_CONFIG_ID:					return configId;
		case EGL_CONFORMANT:				return conformant;
		case EGL_DEPTH_SIZE:				return depthSize;
		case EGL_LEVEL:						return level;
		case EGL_MAX_PBUFFER_WIDTH:			return maxPbufferWidth;
		case EGL_MAX_PBUFFER_HEIGHT:		return maxPbufferHeight;
		case EGL_MAX_SWAP_INTERVAL:			return maxSwapInterval;
		case EGL_MIN_SWAP_INTERVAL:			return minSwapInterval;
		case EGL_NATIVE_RENDERABLE:			return nativeRenderable;
		case EGL_NATIVE_VISUAL_ID:			return nativeVisualId;
		case EGL_NATIVE_VISUAL_TYPE:		return nativeVisualType;
		case EGL_RENDERABLE_TYPE:			return renderableType;
		case EGL_SAMPLE_BUFFERS:			return sampleBuffers;
		case EGL_SAMPLES:					return samples;
		case EGL_STENCIL_SIZE:				return stencilSize;
		case EGL_SURFACE_TYPE:				return surfaceType;
		case EGL_TRANSPARENT_TYPE:			return transparentType;
		case EGL_TRANSPARENT_RED_VALUE:		return transparentRedValue;
		case EGL_TRANSPARENT_GREEN_VALUE:	return transparentGreenValue;
		case EGL_TRANSPARENT_BLUE_VALUE:	return transparentBlueValue;

		// EGL_EXT_yuv_surface
		case EGL_YUV_ORDER_EXT:				return yuvOrder;
		case EGL_YUV_NUMBER_OF_PLANES_EXT:	return yuvNumberOfPlanes;
		case EGL_YUV_SUBSAMPLE_EXT:			return yuvSubsample;
		case EGL_YUV_DEPTH_RANGE_EXT:		return yuvDepthRange;
		case EGL_YUV_CSC_STANDARD_EXT:		return yuvCscStandard;
		case EGL_YUV_PLANE_BPP_EXT:			return yuvPlaneBpp;

		default:							TCU_THROW(InternalError, "Unknown attribute");
	}
}

void queryCoreConfigInfo (const Library& egl, EGLDisplay display, EGLConfig config, ConfigInfo* dst)
{
	egl.getConfigAttrib(display, config, EGL_BUFFER_SIZE,				&dst->bufferSize);
	egl.getConfigAttrib(display, config, EGL_RED_SIZE,					&dst->redSize);
	egl.getConfigAttrib(display, config, EGL_GREEN_SIZE,				&dst->greenSize);
	egl.getConfigAttrib(display, config, EGL_BLUE_SIZE,					&dst->blueSize);
	egl.getConfigAttrib(display, config, EGL_LUMINANCE_SIZE,			&dst->luminanceSize);
	egl.getConfigAttrib(display, config, EGL_ALPHA_SIZE,				&dst->alphaSize);
	egl.getConfigAttrib(display, config, EGL_ALPHA_MASK_SIZE,			&dst->alphaMaskSize);
	egl.getConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGB,		(EGLint*)&dst->bindToTextureRGB);
	egl.getConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_RGBA,		(EGLint*)&dst->bindToTextureRGBA);
	egl.getConfigAttrib(display, config, EGL_COLOR_BUFFER_TYPE,			(EGLint*)&dst->colorBufferType);
	egl.getConfigAttrib(display, config, EGL_CONFIG_CAVEAT,				(EGLint*)&dst->configCaveat);
	egl.getConfigAttrib(display, config, EGL_CONFIG_ID,					&dst->configId);
	egl.getConfigAttrib(display, config, EGL_CONFORMANT,				&dst->conformant);
	egl.getConfigAttrib(display, config, EGL_DEPTH_SIZE,				&dst->depthSize);
	egl.getConfigAttrib(display, config, EGL_LEVEL,						&dst->level);
	egl.getConfigAttrib(display, config, EGL_MAX_PBUFFER_WIDTH,			&dst->maxPbufferWidth);
	egl.getConfigAttrib(display, config, EGL_MAX_PBUFFER_HEIGHT,		&dst->maxPbufferHeight);
	egl.getConfigAttrib(display, config, EGL_MAX_SWAP_INTERVAL,			&dst->maxSwapInterval);
	egl.getConfigAttrib(display, config, EGL_MIN_SWAP_INTERVAL,			&dst->minSwapInterval);
	egl.getConfigAttrib(display, config, EGL_NATIVE_RENDERABLE,			(EGLint*)&dst->nativeRenderable);
	egl.getConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID,			&dst->nativeVisualId);
	egl.getConfigAttrib(display, config, EGL_NATIVE_VISUAL_TYPE,		&dst->nativeVisualType);
	egl.getConfigAttrib(display, config, EGL_RENDERABLE_TYPE,			&dst->renderableType);
	egl.getConfigAttrib(display, config, EGL_SAMPLE_BUFFERS,			&dst->sampleBuffers);
	egl.getConfigAttrib(display, config, EGL_SAMPLES,					&dst->samples);
	egl.getConfigAttrib(display, config, EGL_STENCIL_SIZE,				&dst->stencilSize);
	egl.getConfigAttrib(display, config, EGL_SURFACE_TYPE,				&dst->surfaceType);
	egl.getConfigAttrib(display, config, EGL_TRANSPARENT_TYPE,			(EGLint*)&dst->transparentType);
	egl.getConfigAttrib(display, config, EGL_TRANSPARENT_RED_VALUE,		&dst->transparentRedValue);
	egl.getConfigAttrib(display, config, EGL_TRANSPARENT_GREEN_VALUE,	&dst->transparentGreenValue);
	egl.getConfigAttrib(display, config, EGL_TRANSPARENT_BLUE_VALUE,	&dst->transparentBlueValue);
	EGLU_CHECK_MSG(egl, "Failed to query config info");
}

void queryExtConfigInfo (const eglw::Library& egl, eglw::EGLDisplay display, eglw::EGLConfig config, ConfigInfo* dst)
{
	const std::vector<std::string>	extensions	= getDisplayExtensions(egl, display);

	if (de::contains(extensions.begin(), extensions.end(), "EGL_EXT_yuv_surface"))
	{
		egl.getConfigAttrib(display, config, EGL_YUV_ORDER_EXT,				(EGLint*)&dst->yuvOrder);
		egl.getConfigAttrib(display, config, EGL_YUV_NUMBER_OF_PLANES_EXT,	(EGLint*)&dst->yuvNumberOfPlanes);
		egl.getConfigAttrib(display, config, EGL_YUV_SUBSAMPLE_EXT,			(EGLint*)&dst->yuvSubsample);
		egl.getConfigAttrib(display, config, EGL_YUV_DEPTH_RANGE_EXT,		(EGLint*)&dst->yuvDepthRange);
		egl.getConfigAttrib(display, config, EGL_YUV_CSC_STANDARD_EXT,		(EGLint*)&dst->yuvCscStandard);
		egl.getConfigAttrib(display, config, EGL_YUV_PLANE_BPP_EXT,			(EGLint*)&dst->yuvPlaneBpp);

		EGLU_CHECK_MSG(egl, "Failed to query EGL_EXT_yuv_surface config attribs");
	}
}

} // eglu
