/*
* Copyright (C) 2011 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.
*/
#include "EglValidate.h"
#include <GLcommon/GLutils.h>

#ifndef EGL_PRESERVED_RESOURCES
#define EGL_PRESERVED_RESOURCES 0x3030
#endif

// static
bool EglValidate::confAttrib(EGLint attrib) {
    switch(attrib) {
    case EGL_BUFFER_SIZE:
    case EGL_RED_SIZE:
    case EGL_GREEN_SIZE:
    case EGL_BLUE_SIZE:
    case EGL_ALPHA_SIZE:
    case EGL_ALPHA_MASK_SIZE:
    case EGL_BIND_TO_TEXTURE_RGB:
    case EGL_BIND_TO_TEXTURE_RGBA:
    case EGL_CONFIG_CAVEAT:
    case EGL_CONFIG_ID:
    case EGL_DEPTH_SIZE:
    case EGL_LEVEL:
    case EGL_LUMINANCE_SIZE:
    case EGL_MAX_PBUFFER_WIDTH:
    case EGL_MAX_PBUFFER_HEIGHT:
    case EGL_MAX_PBUFFER_PIXELS:
    case EGL_MAX_SWAP_INTERVAL:
    case EGL_MIN_SWAP_INTERVAL:
    case EGL_PRESERVED_RESOURCES:
    case EGL_RENDERABLE_TYPE:
    case EGL_NATIVE_RENDERABLE:
    case EGL_NATIVE_VISUAL_ID:
    case EGL_NATIVE_VISUAL_TYPE:
    case EGL_SAMPLE_BUFFERS:
    case EGL_SAMPLES:
    case EGL_STENCIL_SIZE:
    case EGL_SURFACE_TYPE:
    case EGL_COLOR_BUFFER_TYPE:
    case EGL_TRANSPARENT_TYPE:
    case EGL_TRANSPARENT_RED_VALUE:
    case EGL_TRANSPARENT_GREEN_VALUE:
    case EGL_TRANSPARENT_BLUE_VALUE:
    case EGL_RECORDABLE_ANDROID:
    case EGL_CONFORMANT:
        return true;
    }
    return false;
}

// static
bool EglValidate::noAttribs(const EGLint* attrib) {
    return !attrib || attrib[0] == EGL_NONE ;
}

// static
bool EglValidate::pbufferAttribs(EGLint width,
                                 EGLint height,
                                 bool isTexFormatNoTex,
                                 bool isTexTargetNoTex) {
    if(!isTexFormatNoTex) {
        if (!(isPowerOf2(width) && isPowerOf2(height))) {
            return false;
        }
    }
    return isTexFormatNoTex == isTexTargetNoTex ;
}

// static
bool EglValidate::releaseContext(EGLContext ctx,
                                 EGLSurface s1,
                                 EGLSurface s2) {
    return (ctx == EGL_NO_CONTEXT) &&
           (s1 == EGL_NO_SURFACE)  &&
           (s2 == EGL_NO_SURFACE);
}

// static
bool EglValidate::badContextMatch(EGLContext ctx,
                                  EGLSurface s1,
                                  EGLSurface s2) {
    return (ctx != EGL_NO_CONTEXT)
            ? (s1 == EGL_NO_SURFACE || s2 == EGL_NO_SURFACE)
            : (s1 != EGL_NO_SURFACE || s2 != EGL_NO_SURFACE);
}

// static
bool EglValidate::surfaceTarget(EGLint target) {
    return target == EGL_READ || target == EGL_DRAW;
}

// static
bool EglValidate::engine(EGLint engine) {
    return engine == EGL_CORE_NATIVE_ENGINE;
}

// static
bool EglValidate::stringName(EGLint name) {
    return name == EGL_VENDOR  ||
           name == EGL_VERSION ||
           name == EGL_EXTENSIONS;
}

// static
bool EglValidate::supportedApi(EGLenum api) {
    return api == EGL_OPENGL_ES_API;
}
