| /* |
| * 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 "renderControl_dec.h" |
| #include "FrameBuffer.h" |
| #include "FBConfig.h" |
| #include "EGLDispatch.h" |
| #include "GLDispatch.h" |
| #include "GL2Dispatch.h" |
| #include "ThreadInfo.h" |
| |
| static const GLint rendererVersion = 1; |
| |
| static GLint rcGetRendererVersion() |
| { |
| return rendererVersion; |
| } |
| |
| static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return EGL_FALSE; |
| } |
| *major = (EGLint)fb->getCaps().eglMajor; |
| *minor = (EGLint)fb->getCaps().eglMinor; |
| |
| return EGL_TRUE; |
| } |
| |
| static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| const char *str = s_egl.eglQueryString(fb->getDisplay(), name); |
| if (!str) { |
| return 0; |
| } |
| |
| int len = strlen(str) + 1; |
| if (!buffer || len > bufferSize) { |
| return -len; |
| } |
| |
| strcpy((char *)buffer, str); |
| return len; |
| } |
| |
| static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) |
| { |
| RenderThreadInfo *tInfo = getRenderThreadInfo(); |
| if (!tInfo || !tInfo->currContext.Ptr()) { |
| return 0; |
| } |
| |
| const char *str = NULL; |
| #ifdef WITH_GLES2 |
| if (tInfo->currContext->isGL2()) { |
| str = (const char *)s_gl2.glGetString(name); |
| } |
| else { |
| #endif |
| str = (const char *)s_gl.glGetString(name); |
| #ifdef WITH_GLES2 |
| } |
| #endif |
| |
| if (!str) { |
| return 0; |
| } |
| |
| int len = strlen(str) + 1; |
| if (!buffer || len > bufferSize) { |
| return -len; |
| } |
| |
| strcpy((char *)buffer, str); |
| return len; |
| } |
| |
| static EGLint rcGetNumConfigs(uint32_t* numAttribs) |
| { |
| if (numAttribs) { |
| *numAttribs = FBConfig::getNumAttribs(); |
| } |
| return FBConfig::getNumConfigs(); |
| } |
| |
| static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer) |
| { |
| int configSize = FBConfig::getNumAttribs(); |
| int nConfigs = FBConfig::getNumConfigs(); |
| uint32_t neededSize = (nConfigs + 1) * configSize * sizeof(GLuint); |
| if (!buffer || bufSize < neededSize) { |
| return -neededSize; |
| } |
| FBConfig::packConfigsInfo(buffer); |
| return nConfigs; |
| } |
| |
| static EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| return FBConfig::chooseConfig(fb, attribs, configs, configs_size); |
| } |
| |
| static EGLint rcGetFBParam(EGLint param) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| EGLint ret = 0; |
| |
| switch(param) { |
| case FB_WIDTH: |
| ret = fb->getWidth(); |
| break; |
| case FB_HEIGHT: |
| ret = fb->getHeight(); |
| break; |
| case FB_XDPI: |
| ret = 72; // XXX: should be implemented |
| break; |
| case FB_YDPI: |
| ret = 72; // XXX: should be implemented |
| break; |
| case FB_FPS: |
| ret = 60; |
| break; |
| case FB_MIN_SWAP_INTERVAL: |
| ret = 1; // XXX: should be implemented |
| break; |
| case FB_MAX_SWAP_INTERVAL: |
| ret = 1; // XXX: should be implemented |
| break; |
| default: |
| break; |
| } |
| |
| return ret; |
| } |
| |
| static uint32_t rcCreateContext(uint32_t config, |
| uint32_t share, uint32_t glVersion) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| HandleType ret = fb->createRenderContext(config, share, glVersion == 2); |
| return ret; |
| } |
| |
| static void rcDestroyContext(uint32_t context) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| |
| fb->DestroyRenderContext(context); |
| } |
| |
| static uint32_t rcCreateWindowSurface(uint32_t config, |
| uint32_t width, uint32_t height) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| return fb->createWindowSurface(config, width, height); |
| } |
| |
| static void rcDestroyWindowSurface(uint32_t windowSurface) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| |
| fb->DestroyWindowSurface( windowSurface ); |
| } |
| |
| static uint32_t rcCreateColorBuffer(uint32_t width, |
| uint32_t height, GLenum internalFormat) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return 0; |
| } |
| |
| return fb->createColorBuffer(width, height, internalFormat); |
| } |
| |
| static void rcOpenColorBuffer(uint32_t colorbuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| fb->openColorBuffer( colorbuffer ); |
| } |
| |
| static void rcCloseColorBuffer(uint32_t colorbuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| fb->closeColorBuffer( colorbuffer ); |
| } |
| |
| static int rcFlushWindowColorBuffer(uint32_t windowSurface) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return -1; |
| } |
| fb->flushWindowSurfaceColorBuffer(windowSurface); |
| return 0; |
| } |
| |
| static void rcSetWindowColorBuffer(uint32_t windowSurface, |
| uint32_t colorBuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| fb->setWindowSurfaceColorBuffer(windowSurface, colorBuffer); |
| } |
| |
| static EGLint rcMakeCurrent(uint32_t context, |
| uint32_t drawSurf, uint32_t readSurf) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return EGL_FALSE; |
| } |
| |
| bool ret = fb->bindContext(context, drawSurf, readSurf); |
| |
| return (ret ? EGL_TRUE : EGL_FALSE); |
| } |
| |
| static void rcFBPost(uint32_t colorBuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| |
| fb->post(colorBuffer); |
| } |
| |
| static void rcFBSetSwapInterval(EGLint interval) |
| { |
| // XXX: TBD - should be implemented |
| } |
| |
| static void rcBindTexture(uint32_t colorBuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| |
| fb->bindColorBufferToTexture(colorBuffer); |
| } |
| |
| static void rcBindRenderbuffer(uint32_t colorBuffer) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return; |
| } |
| |
| fb->bindColorBufferToRenderbuffer(colorBuffer); |
| } |
| |
| static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer, |
| EGLint postCount, int forRead) |
| { |
| // XXX: TBD - should be implemented |
| return 0; |
| } |
| |
| static void rcReadColorBuffer(uint32_t colorBuffer, |
| GLint x, GLint y, |
| GLint width, GLint height, |
| GLenum format, GLenum type, void* pixels) |
| { |
| // XXX: TBD - should be implemented |
| } |
| |
| static int rcUpdateColorBuffer(uint32_t colorBuffer, |
| GLint x, GLint y, |
| GLint width, GLint height, |
| GLenum format, GLenum type, void* pixels) |
| { |
| FrameBuffer *fb = FrameBuffer::getFB(); |
| if (!fb) { |
| return -1; |
| } |
| |
| fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); |
| return 0; |
| } |
| |
| void initRenderControlContext(renderControl_decoder_context_t *dec) |
| { |
| dec->set_rcGetRendererVersion(rcGetRendererVersion); |
| dec->set_rcGetEGLVersion(rcGetEGLVersion); |
| dec->set_rcQueryEGLString(rcQueryEGLString); |
| dec->set_rcGetGLString(rcGetGLString); |
| dec->set_rcGetNumConfigs(rcGetNumConfigs); |
| dec->set_rcGetConfigs(rcGetConfigs); |
| dec->set_rcChooseConfig(rcChooseConfig); |
| dec->set_rcGetFBParam(rcGetFBParam); |
| dec->set_rcCreateContext(rcCreateContext); |
| dec->set_rcDestroyContext(rcDestroyContext); |
| dec->set_rcCreateWindowSurface(rcCreateWindowSurface); |
| dec->set_rcDestroyWindowSurface(rcDestroyWindowSurface); |
| dec->set_rcCreateColorBuffer(rcCreateColorBuffer); |
| dec->set_rcOpenColorBuffer(rcOpenColorBuffer); |
| dec->set_rcCloseColorBuffer(rcCloseColorBuffer); |
| dec->set_rcSetWindowColorBuffer(rcSetWindowColorBuffer); |
| dec->set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer); |
| dec->set_rcMakeCurrent(rcMakeCurrent); |
| dec->set_rcFBPost(rcFBPost); |
| dec->set_rcFBSetSwapInterval(rcFBSetSwapInterval); |
| dec->set_rcBindTexture(rcBindTexture); |
| dec->set_rcBindRenderbuffer(rcBindRenderbuffer); |
| dec->set_rcColorBufferCacheFlush(rcColorBufferCacheFlush); |
| dec->set_rcReadColorBuffer(rcReadColorBuffer); |
| dec->set_rcUpdateColorBuffer(rcUpdateColorBuffer); |
| } |