X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FWindowSurface.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FWindowSurface.cpp;h=fd60aba7e1f16250b32a44d0eeb39d746a961456;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/WindowSurface.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/WindowSurface.cpp new file mode 100644 index 0000000..fd60aba --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/WindowSurface.cpp @@ -0,0 +1,171 @@ +/* +* 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 "anbox/graphics/emugl/WindowSurface.h" +#include "anbox/graphics/emugl/RendererConfig.h" +#include "anbox/logger.h" + +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" + +#include + +#include +#include + + +WindowSurface::WindowSurface(EGLDisplay display, EGLConfig config) + : mSurface(NULL), + mAttachedColorBuffer(NULL), + mReadContext(NULL), + mDrawContext(NULL), + mWidth(0), + mHeight(0), + mConfig(config), + mDisplay(display) {} + +WindowSurface::~WindowSurface() { + if (mSurface) { + s_egl.eglDestroySurface(mDisplay, mSurface); + } +} + +WindowSurface *WindowSurface::create(EGLDisplay display, EGLConfig config, + int p_width, int p_height) { + // allocate space for the WindowSurface object + WindowSurface *win = new WindowSurface(display, config); + if (!win) { + return NULL; + } + + // Create a pbuffer to be used as the egl surface + // for that window. + if (!win->resize(p_width, p_height)) { + delete win; + return NULL; + } + + return win; +} + +void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) { + mAttachedColorBuffer = p_colorBuffer; + + // resize the window if the attached color buffer is of different + // size. + unsigned int cbWidth = mAttachedColorBuffer->getWidth(); + unsigned int cbHeight = mAttachedColorBuffer->getHeight(); + + if (cbWidth != mWidth || cbHeight != mHeight) { + resize(cbWidth, cbHeight); + } +} + +void WindowSurface::bind(RenderContextPtr p_ctx, BindType p_bindType) { + if (p_bindType == BIND_READ) { + mReadContext = p_ctx; + } else if (p_bindType == BIND_DRAW) { + mDrawContext = p_ctx; + } else if (p_bindType == BIND_READDRAW) { + mReadContext = p_ctx; + mDrawContext = p_ctx; + } +} + +bool WindowSurface::flushColorBuffer() { + if (!mAttachedColorBuffer) { + return true; + } + if (!mWidth || !mHeight) { + return false; + } + + if (mAttachedColorBuffer->getWidth() != mWidth || + mAttachedColorBuffer->getHeight() != mHeight) { + // XXX: should never happen - how this needs to be handled? + ERROR("Dimensions do not match"); + return false; + } + + if (!mDrawContext) { + ERROR("Draw context is NULL"); + return false; + } + + // Make the surface current + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + + if (!s_egl.eglMakeCurrent(mDisplay, mSurface, mSurface, + mDrawContext->getEGLContext())) { + ERROR("Failed to make draw context current"); + return false; + } + + mAttachedColorBuffer->blitFromCurrentReadBuffer(); + + // restore current context/surface + s_egl.eglMakeCurrent(mDisplay, prevDrawSurf, prevReadSurf, prevContext); + + return true; +} + +bool WindowSurface::resize(unsigned int p_width, unsigned int p_height) { + if (mSurface && mWidth == p_width && mHeight == p_height) { + // no need to resize + return true; + } + + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + EGLSurface prevPbuf = mSurface; + bool needRebindContext = + mSurface && (prevReadSurf == mSurface || prevDrawSurf == mSurface); + + if (needRebindContext) { + s_egl.eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, + EGL_NO_CONTEXT); + } + + if (mSurface) { + s_egl.eglDestroySurface(mDisplay, mSurface); + mSurface = NULL; + } + + const EGLint pbufAttribs[5] = { + EGL_WIDTH, static_cast(p_width), + EGL_HEIGHT, static_cast(p_height), + EGL_NONE, + }; + + mSurface = s_egl.eglCreatePbufferSurface(mDisplay, mConfig, pbufAttribs); + if (mSurface == EGL_NO_SURFACE) { + ERROR("Failed to create/resize pbuffer"); + return false; + } + + mWidth = p_width; + mHeight = p_height; + + if (needRebindContext) { + s_egl.eglMakeCurrent( + mDisplay, (prevDrawSurf == prevPbuf) ? mSurface : prevDrawSurf, + (prevReadSurf == prevPbuf) ? mSurface : prevReadSurf, prevContext); + } + + return true; +}