blob: 6a050ce16305ee23c5226ed88af68ed3cd18298c [file] [log] [blame]
/*
* 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 <GLcommon/GLutils.h>
#include "aemu/base/synchronization/Lock.h"
#include <GLES/gl.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#include <GLES3/gl31.h>
bool isPowerOf2(int num) {
return (num & (num -1)) == 0;
}
android::base::StaticLock sGlobalSettingsLock;
static uint32_t s_gles2Gles = 0;
static uint32_t s_coreProfile = 0;
void setGles2Gles(bool isGles2Gles) {
__atomic_store_n(&s_gles2Gles, isGles2Gles ? 1 : 0, __ATOMIC_RELAXED);
}
bool isGles2Gles() {
return __atomic_load_n(&s_gles2Gles, __ATOMIC_RELAXED) != 0;
}
void setCoreProfile(bool isCore) {
__atomic_store_n(&s_coreProfile, isCore ? 1 : 0, __ATOMIC_RELAXED);
}
bool isCoreProfile() {
return __atomic_load_n(&s_coreProfile, __ATOMIC_RELAXED) != 0;
}
FramebufferChannelBits glFormatToChannelBits(GLenum colorFormat,
GLenum depthFormat,
GLenum stencilFormat) {
FramebufferChannelBits res = {};
#define COLOR_BITS_CASE(format, r, g, b, a) \
case format: res.red = r; res.green = g; res.blue = b; res.alpha = a; break; \
switch (colorFormat) {
COLOR_BITS_CASE(GL_ALPHA, 0, 0, 0, 8)
COLOR_BITS_CASE(GL_LUMINANCE, 0, 0, 0, 0)
COLOR_BITS_CASE(GL_LUMINANCE_ALPHA, 0, 0, 0, 8)
COLOR_BITS_CASE(GL_RGB, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_RGBA, 8, 8, 8, 8)
COLOR_BITS_CASE(GL_R11F_G11F_B10F, 11, 11, 10, 0)
COLOR_BITS_CASE(GL_R16F, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_R16I, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_R16UI, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_R32F, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_R32I, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_R32UI, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_R8, 8, 0, 0, 0)
COLOR_BITS_CASE(GL_R8I, 8, 0, 0, 0)
COLOR_BITS_CASE(GL_R8_SNORM, 8, 0, 0, 0)
COLOR_BITS_CASE(GL_R8UI, 8, 0, 0, 0)
COLOR_BITS_CASE(GL_RG16F, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_RG16I, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_RG16UI, 16, 0, 0, 0)
COLOR_BITS_CASE(GL_RG32F, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_RG32I, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_RG32UI, 32, 0, 0, 0)
COLOR_BITS_CASE(GL_RG8, 8, 8, 0, 0)
COLOR_BITS_CASE(GL_RG8I, 8, 8, 0, 0)
COLOR_BITS_CASE(GL_RG8_SNORM, 8, 8, 0, 0)
COLOR_BITS_CASE(GL_RG8UI, 8, 8, 0, 0)
COLOR_BITS_CASE(GL_RGB10_A2, 10, 10, 10, 2)
COLOR_BITS_CASE(GL_RGB10_A2UI, 10, 10, 10, 2)
COLOR_BITS_CASE(GL_RGB16F, 16, 16, 16, 0)
COLOR_BITS_CASE(GL_RGB16I, 16, 16, 16, 0)
COLOR_BITS_CASE(GL_RGB16UI, 16, 16, 16, 0)
COLOR_BITS_CASE(GL_RGB32F, 32, 32, 32, 0)
COLOR_BITS_CASE(GL_RGB32I, 32, 32, 32, 0)
COLOR_BITS_CASE(GL_RGB32UI, 32, 32, 32, 0)
COLOR_BITS_CASE(GL_RGB565, 5, 6, 5, 0)
COLOR_BITS_CASE(GL_RGB5_A1, 5, 5, 5, 1)
COLOR_BITS_CASE(GL_RGB8, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_RGB8I, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_RGB8_SNORM, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_RGB8UI, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_RGB9_E5, 9, 9, 9, 0)
COLOR_BITS_CASE(GL_RGBA16F, 16, 16, 16, 16)
COLOR_BITS_CASE(GL_RGBA16I, 16, 16, 16, 16)
COLOR_BITS_CASE(GL_RGBA16UI, 16, 16, 16, 16)
COLOR_BITS_CASE(GL_RGBA32F, 32, 32, 32, 32)
COLOR_BITS_CASE(GL_RGBA32I, 32, 32, 32, 32)
COLOR_BITS_CASE(GL_RGBA32UI, 32, 32, 32, 32)
COLOR_BITS_CASE(GL_RGBA4, 4, 4, 4, 4)
COLOR_BITS_CASE(GL_RGBA8, 8, 8, 8, 8)
COLOR_BITS_CASE(GL_RGBA8I, 8, 8, 8, 8)
COLOR_BITS_CASE(GL_RGBA8_SNORM, 8, 8, 8, 8)
COLOR_BITS_CASE(GL_RGBA8UI, 8, 8, 8, 8)
COLOR_BITS_CASE(GL_SRGB8, 8, 8, 8, 0)
COLOR_BITS_CASE(GL_SRGB8_ALPHA8, 8, 8, 8, 8)
}
#define DEPTH_BITS_CASE(format, d) \
case format: res.depth = d; break; \
switch (depthFormat) {
DEPTH_BITS_CASE(GL_DEPTH_COMPONENT16, 16)
DEPTH_BITS_CASE(GL_DEPTH_COMPONENT24, 24)
DEPTH_BITS_CASE(GL_DEPTH_COMPONENT32F, 32)
DEPTH_BITS_CASE(GL_DEPTH24_STENCIL8, 24)
DEPTH_BITS_CASE(GL_DEPTH32F_STENCIL8, 32)
DEPTH_BITS_CASE(GL_STENCIL_INDEX8, 0)
}
#define STENCIL_BITS_CASE(format, d) \
case format: res.stencil = d; break; \
switch (stencilFormat) {
STENCIL_BITS_CASE(GL_DEPTH_COMPONENT16, 0)
STENCIL_BITS_CASE(GL_DEPTH_COMPONENT24, 0)
STENCIL_BITS_CASE(GL_DEPTH_COMPONENT32F, 0)
STENCIL_BITS_CASE(GL_DEPTH24_STENCIL8, 8)
STENCIL_BITS_CASE(GL_DEPTH32F_STENCIL8, 8)
STENCIL_BITS_CASE(GL_STENCIL_INDEX8, 8)
}
return res;
}
GLenum baseFormatOfInternalFormat(GLint internalformat) {
switch (internalformat) {
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_RGBA:
return internalformat;
case GL_R8:
case GL_R8_SNORM:
case GL_R16F:
case GL_R32F:
return GL_RED;
case GL_R8I:
case GL_R8UI:
case GL_R16I:
case GL_R16UI:
case GL_R32I:
case GL_R32UI:
return GL_RED_INTEGER;
case GL_RG8:
case GL_RG8_SNORM:
case GL_RG16F:
case GL_RG32F:
return GL_RG;
case GL_RG8I:
case GL_RG8UI:
case GL_RG16I:
case GL_RG16UI:
case GL_RG32I:
case GL_RG32UI:
return GL_RG_INTEGER;
case GL_RGB565:
case GL_RGB8:
case GL_SRGB8:
case GL_RGB8_SNORM:
case GL_RGB9_E5:
case GL_R11F_G11F_B10F:
case GL_RGB16F:
case GL_RGB32F:
return GL_RGB;
case GL_RGB8I:
case GL_RGB8UI:
case GL_RGB16I:
case GL_RGB16UI:
case GL_RGB32I:
case GL_RGB32UI:
return GL_RGB_INTEGER;
case GL_RGBA4:
case GL_RGB5_A1:
case GL_RGBA8:
case GL_SRGB8_ALPHA8:
case GL_RGBA8_SNORM:
case GL_RGB10_A2:
case GL_RGBA16F:
case GL_RGBA32F:
return GL_RGBA;
case GL_RGBA8I:
case GL_RGBA8UI:
case GL_RGB10_A2UI:
case GL_RGBA16I:
case GL_RGBA16UI:
case GL_RGBA32I:
case GL_RGBA32UI:
return GL_RGBA_INTEGER;
case GL_DEPTH_COMPONENT16:
case GL_DEPTH_COMPONENT24:
case GL_DEPTH_COMPONENT32F:
return GL_DEPTH_COMPONENT;
case GL_DEPTH24_STENCIL8:
case GL_DEPTH32F_STENCIL8:
return GL_DEPTH_STENCIL;
case GL_STENCIL_INDEX8:
return GL_STENCIL;
}
fprintf(stderr, "%s: warning: unrecognized internal format 0x%x\n", __func__,
internalformat);
return internalformat;
}
GLenum accurateTypeOfInternalFormat(GLint internalformat) {
switch (internalformat) {
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_RGBA:
case GL_R8:
case GL_R8_SNORM:
case GL_RG8:
case GL_RG8_SNORM:
case GL_RGB8:
case GL_SRGB8:
case GL_RGB8_SNORM:
case GL_RGBA8:
case GL_SRGB8_ALPHA8:
case GL_RGBA8_SNORM:
case GL_R8UI:
case GL_RG8UI:
case GL_RGB8UI:
case GL_RGBA8UI:
return GL_UNSIGNED_BYTE;
case GL_R8I:
case GL_RG8I:
case GL_RGB8I:
case GL_RGBA8I:
return GL_BYTE;
case GL_R16UI:
case GL_RG16UI:
case GL_RGB16UI:
case GL_RGBA16UI:
case GL_DEPTH_COMPONENT16:
return GL_UNSIGNED_SHORT;
case GL_R16I:
case GL_RG16I:
case GL_RGB16I:
case GL_RGBA16I:
return GL_SHORT;
case GL_R32UI:
case GL_RG32UI:
case GL_RGB32UI:
case GL_RGBA32UI:
case GL_DEPTH_COMPONENT24:
return GL_UNSIGNED_INT;
case GL_R32I:
case GL_RG32I:
case GL_RGB32I:
case GL_RGBA32I:
return GL_INT;
case GL_R16F:
case GL_RG16F:
case GL_RGB16F:
case GL_RGBA16F:
return GL_HALF_FLOAT;
case GL_R32F:
case GL_RG32F:
case GL_RGB32F:
case GL_RGBA32F:
case GL_DEPTH_COMPONENT32F:
return GL_FLOAT;
case GL_DEPTH24_STENCIL8:
return GL_UNSIGNED_INT_24_8;
case GL_DEPTH32F_STENCIL8:
return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
case GL_RGB565:
return GL_UNSIGNED_SHORT_5_6_5;
case GL_RGB9_E5:
return GL_UNSIGNED_INT_5_9_9_9_REV;
case GL_R11F_G11F_B10F:
return GL_UNSIGNED_INT_10F_11F_11F_REV;
case GL_RGBA4:
return GL_UNSIGNED_SHORT_4_4_4_4;
case GL_RGB5_A1:
return GL_UNSIGNED_SHORT_5_5_5_1;
case GL_RGB10_A2:
case GL_RGB10_A2UI:
return GL_UNSIGNED_INT_2_10_10_10_REV;
case GL_STENCIL_INDEX8:
return GL_UNSIGNED_BYTE;
}
fprintf(stderr, "%s: warning: unrecognized internal format 0x%x\n", __func__,
internalformat);
return GL_UNSIGNED_BYTE;
}