RenderEngine.cpp revision 875d8e1323536e16dcfc90c9674d7ad32116a69a
1/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cutils/log.h>
18
19#include "RenderEngine.h"
20#include "GLES10RenderEngine.h"
21#include "GLES11RenderEngine.h"
22#include "GLExtensions.h"
23
24// ---------------------------------------------------------------------------
25namespace android {
26// ---------------------------------------------------------------------------
27
28RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
29    // Also create our EGLContext
30    EGLint contextAttributes[] = {
31//            EGL_CONTEXT_CLIENT_VERSION, 2,
32#ifdef EGL_IMG_context_priority
33#ifdef HAS_CONTEXT_PRIORITY
34#warning "using EGL_IMG_context_priority"
35            EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
36#endif
37#endif
38            EGL_NONE, EGL_NONE
39    };
40
41    EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
42    if (ctxt == EGL_NO_CONTEXT) {
43        // maybe ES 2.x is not supported
44        ALOGW("can't create an ES 2.x context, trying 1.x");
45        ctxt = eglCreateContext(display, config, NULL, contextAttributes + 2);
46    }
47
48    // if can't create a GL context, we can only abort.
49    LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
50
51
52    // now figure out what version of GL did we actually get
53    // NOTE: a dummy surface is not needed if KHR_create_context is supported
54
55    EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE };
56    EGLSurface dummy = eglCreatePbufferSurface(display, config, attribs);
57    LOG_ALWAYS_FATAL_IF(dummy==EGL_NO_SURFACE, "can't create dummy pbuffer");
58    EGLBoolean success = eglMakeCurrent(display, dummy, dummy, ctxt);
59    LOG_ALWAYS_FATAL_IF(!success, "can't make dummy pbuffer current");
60
61    GLExtensions& extensions(GLExtensions::getInstance());
62    extensions.initWithGLStrings(
63            glGetString(GL_VENDOR),
64            glGetString(GL_RENDERER),
65            glGetString(GL_VERSION),
66            glGetString(GL_EXTENSIONS));
67
68    GlesVersion version = parseGlesVersion( extensions.getVersion() );
69
70    // initialize the renderer while GL is current
71
72    RenderEngine* engine = NULL;
73    switch (version) {
74    case GLES_VERSION_1_0:
75        engine = new GLES10RenderEngine();
76        break;
77    case GLES_VERSION_1_1:
78        engine = new GLES11RenderEngine();
79        break;
80    case GLES_VERSION_2_0:
81    case GLES_VERSION_3_0:
82        //engine = new GLES20RenderEngine();
83        break;
84    }
85    engine->setEGLContext(ctxt);
86
87    ALOGI("OpenGL ES informations:");
88    ALOGI("vendor    : %s", extensions.getVendor());
89    ALOGI("renderer  : %s", extensions.getRenderer());
90    ALOGI("version   : %s", extensions.getVersion());
91    ALOGI("extensions: %s", extensions.getExtension());
92    ALOGI("GL_MAX_TEXTURE_SIZE = %d", engine->getMaxTextureSize());
93    ALOGI("GL_MAX_VIEWPORT_DIMS = %d", engine->getMaxViewportDims());
94
95    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
96    eglDestroySurface(display, dummy);
97
98    return engine;
99}
100
101RenderEngine::RenderEngine() : mEGLContext(EGL_NO_CONTEXT) {
102}
103
104RenderEngine::~RenderEngine() {
105}
106
107void RenderEngine::setEGLContext(EGLContext ctxt) {
108    mEGLContext = ctxt;
109}
110
111EGLContext RenderEngine::getEGLContext() const {
112    return mEGLContext;
113}
114
115void RenderEngine::checkErrors() const {
116    do {
117        // there could be more than one error flag
118        GLenum error = glGetError();
119        if (error == GL_NO_ERROR)
120            break;
121        ALOGE("GL error 0x%04x", int(error));
122    } while (true);
123}
124
125RenderEngine::GlesVersion RenderEngine::parseGlesVersion(const char* str) {
126    int major, minor;
127    if (sscanf(str, "OpenGL ES-CM %d.%d", &major, &minor) != 2) {
128        if (sscanf(str, "OpenGL ES %d.%d", &major, &minor) != 2) {
129            ALOGW("Unable to parse GL_VERSION string: \"%s\"", str);
130            return GLES_VERSION_1_0;
131        }
132    }
133
134    if (major == 1 && minor == 0) return GLES_VERSION_1_0;
135    if (major == 1 && minor >= 1) return GLES_VERSION_1_1;
136    if (major == 2 && minor >= 0) return GLES_VERSION_2_0;
137    if (major == 3 && minor >= 0) return GLES_VERSION_3_0;
138
139    ALOGW("Unrecognized OpenGL ES version: %d.%d", major, minor);
140    return GLES_VERSION_1_0;
141}
142
143// ---------------------------------------------------------------------------
144}; // namespace android
145// ---------------------------------------------------------------------------
146