X-Git-Url: https://gerrit.akraino.org/r/gitweb?a=blobdiff_plain;f=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FRendererConfig.cpp;fp=src%2Ftype3_AndroidCloud%2Fanbox-master%2Fsrc%2Fanbox%2Fgraphics%2Femugl%2FRendererConfig.cpp;h=02b6b78823b9fff07270f01cd13f81c75ee5d79b;hb=e26c1ec581be598521517829adba8c8dd23a768f;hp=0000000000000000000000000000000000000000;hpb=6699c1aea74eeb0eb400e6299079f0c7576f716f;p=iec.git diff --git a/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/RendererConfig.cpp b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/RendererConfig.cpp new file mode 100644 index 0000000..02b6b78 --- /dev/null +++ b/src/type3_AndroidCloud/anbox-master/src/anbox/graphics/emugl/RendererConfig.cpp @@ -0,0 +1,238 @@ +// Copyright (C) 2015 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/RendererConfig.h" +#include "anbox/logger.h" + +#include "external/android-emugl/host/include/OpenGLESDispatch/EGLDispatch.h" + +#include +#include + +namespace { +const GLuint kConfigAttributes[] = { + EGL_DEPTH_SIZE, // must be first - see getDepthSize() + EGL_STENCIL_SIZE, // must be second - see getStencilSize() + EGL_RENDERABLE_TYPE, // must be third - see getRenderableType() + EGL_SURFACE_TYPE, // must be fourth - see getSurfaceType() + EGL_CONFIG_ID, // must be fifth - see chooseConfig() + EGL_BUFFER_SIZE, EGL_ALPHA_SIZE, EGL_BLUE_SIZE, EGL_GREEN_SIZE, + EGL_RED_SIZE, EGL_CONFIG_CAVEAT, EGL_LEVEL, EGL_MAX_PBUFFER_HEIGHT, + EGL_MAX_PBUFFER_PIXELS, EGL_MAX_PBUFFER_WIDTH, EGL_NATIVE_RENDERABLE, + EGL_NATIVE_VISUAL_ID, EGL_NATIVE_VISUAL_TYPE, EGL_SAMPLES, + EGL_SAMPLE_BUFFERS, EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_BLUE_VALUE, + EGL_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_RED_VALUE, + EGL_BIND_TO_TEXTURE_RGB, EGL_BIND_TO_TEXTURE_RGBA, EGL_MIN_SWAP_INTERVAL, + EGL_MAX_SWAP_INTERVAL, EGL_LUMINANCE_SIZE, EGL_ALPHA_MASK_SIZE, + EGL_COLOR_BUFFER_TYPE, + // EGL_MATCH_NATIVE_PIXMAP, + EGL_CONFORMANT}; + +const size_t kConfigAttributesLen = + sizeof(kConfigAttributes) / sizeof(kConfigAttributes[0]); + +bool isCompatibleHostConfig(EGLConfig config, EGLDisplay display) { + // Filter out configs which do not support pbuffers, since they + // are used to implement window surfaces. + EGLint surfaceType; + s_egl.eglGetConfigAttrib(display, config, EGL_SURFACE_TYPE, &surfaceType); + if (!(surfaceType & EGL_PBUFFER_BIT)) { + return false; + } + + // Filter out configs that do not support RGB pixel values. + EGLint redSize = 0, greenSize = 0, blueSize = 0; + s_egl.eglGetConfigAttrib(display, config, EGL_RED_SIZE, &redSize); + s_egl.eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &greenSize); + s_egl.eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &blueSize); + + if (!redSize || !greenSize || !blueSize) { + return false; + } + + return true; +} +} // namespace + +RendererConfig::~RendererConfig() { delete[] mAttribValues; } + +RendererConfig::RendererConfig(EGLConfig hostConfig, EGLDisplay hostDisplay) + : mEglConfig(hostConfig), mAttribValues(NULL) { + mAttribValues = new GLint[kConfigAttributesLen]; + for (size_t i = 0; i < kConfigAttributesLen; ++i) { + mAttribValues[i] = 0; + s_egl.eglGetConfigAttrib(hostDisplay, hostConfig, kConfigAttributes[i], + &mAttribValues[i]); + + // This implementation supports guest window surfaces by wrapping + // them around host Pbuffers, so always report it to the guest. + if (kConfigAttributes[i] == EGL_SURFACE_TYPE) { + mAttribValues[i] |= EGL_WINDOW_BIT; + } + } +} + +RendererConfigList::RendererConfigList(EGLDisplay display) + : mCount(0), mConfigs(NULL), mDisplay(display) { + if (display == EGL_NO_DISPLAY) { + ERROR("Invalid display value %p (EGL_NO_DISPLAY)", reinterpret_cast(display)); + return; + } + + EGLint numHostConfigs = 0; + if (!s_egl.eglGetConfigs(display, NULL, 0, &numHostConfigs)) { + ERROR("Could not get number of host EGL config"); + return; + } + EGLConfig* hostConfigs = new EGLConfig[numHostConfigs]; + s_egl.eglGetConfigs(display, hostConfigs, numHostConfigs, &numHostConfigs); + + mConfigs = new RendererConfig*[numHostConfigs]; + for (EGLint i = 0; i < numHostConfigs; ++i) { + // Filter out configs that are not compatible with our implementation. + if (!isCompatibleHostConfig(hostConfigs[i], display)) { + continue; + } + mConfigs[mCount] = new RendererConfig(hostConfigs[i], display); + mCount++; + } + + delete[] hostConfigs; +} + +RendererConfigList::~RendererConfigList() { + for (int n = 0; n < mCount; ++n) { + delete mConfigs[n]; + } + delete[] mConfigs; +} + +int RendererConfigList::chooseConfig(const EGLint* attribs, EGLint* configs, + EGLint configsSize) const { + EGLint numHostConfigs = 0; + if (!s_egl.eglGetConfigs(mDisplay, NULL, 0, &numHostConfigs)) { + ERROR("Could not get number of host EGL configs"); + return 0; + } + + EGLConfig* matchedConfigs = new EGLConfig[numHostConfigs]; + + // If EGL_SURFACE_TYPE appears in |attribs|, the value passed to + // eglChooseConfig should be forced to EGL_PBUFFER_BIT because that's + // what it used by the current implementation, exclusively. This forces + // the rewrite of |attribs| into a new array. + bool hasSurfaceType = false; + bool mustReplaceSurfaceType = false; + int numAttribs = 0; + while (attribs[numAttribs] != EGL_NONE) { + if (attribs[numAttribs] == EGL_SURFACE_TYPE) { + hasSurfaceType = true; + if (attribs[numAttribs + 1] != EGL_PBUFFER_BIT) { + mustReplaceSurfaceType = true; + } + } + numAttribs += 2; + } + + EGLint* newAttribs = NULL; + + if (mustReplaceSurfaceType) { + // There is at least on EGL_SURFACE_TYPE in |attribs|. Copy the + // array and replace all values with EGL_PBUFFER_BIT + newAttribs = new GLint[numAttribs + 1]; + memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); + newAttribs[numAttribs] = EGL_NONE; + for (int n = 0; n < numAttribs; n += 2) { + if (newAttribs[n] == EGL_SURFACE_TYPE) { + newAttribs[n + 1] = EGL_PBUFFER_BIT; + } + } + } else if (!hasSurfaceType) { + // There is no EGL_SURFACE_TYPE in |attribs|, then add one entry + // with the value EGL_PBUFFER_BIT. + newAttribs = new GLint[numAttribs + 3]; + memcpy(newAttribs, attribs, numAttribs * sizeof(GLint)); + newAttribs[numAttribs] = EGL_SURFACE_TYPE; + newAttribs[numAttribs + 1] = EGL_PBUFFER_BIT; + newAttribs[numAttribs + 2] = EGL_NONE; + } + + if (!s_egl.eglChooseConfig(mDisplay, newAttribs ? newAttribs : attribs, + matchedConfigs, numHostConfigs, &numHostConfigs)) { + numHostConfigs = 0; + } + + delete[] newAttribs; + + int result = 0; + for (int n = 0; n < numHostConfigs; ++n) { + // Don't count or write more than |configsSize| items if |configs| + // is not NULL. + if (configs && configsSize > 0 && result >= configsSize) { + break; + } + // Skip incompatible host configs. + if (!isCompatibleHostConfig(matchedConfigs[n], mDisplay)) { + continue; + } + // Find the FbConfig with the same EGL_CONFIG_ID + EGLint hostConfigId; + s_egl.eglGetConfigAttrib(mDisplay, matchedConfigs[n], EGL_CONFIG_ID, + &hostConfigId); + for (int k = 0; k < mCount; ++k) { + int guestConfigId = mConfigs[k]->getConfigId(); + if (guestConfigId == hostConfigId) { + // There is a match. Write it to |configs| if it is not NULL. + if (configs && result < configsSize) { + configs[result] = static_cast(k); + } + result++; + break; + } + } + } + + delete[] matchedConfigs; + + return result; +} + +void RendererConfigList::getPackInfo(EGLint* numConfigs, + EGLint* numAttributes) const { + if (numConfigs) { + *numConfigs = mCount; + } + if (numAttributes) { + *numAttributes = static_cast(kConfigAttributesLen); + } +} + +EGLint RendererConfigList::packConfigs(GLuint bufferByteSize, + GLuint* buffer) const { + GLuint numAttribs = static_cast(kConfigAttributesLen); + GLuint kGLuintSize = static_cast(sizeof(GLuint)); + GLuint neededByteSize = (mCount + 1) * numAttribs * kGLuintSize; + if (!buffer || bufferByteSize < neededByteSize) { + return -neededByteSize; + } + // Write to the buffer the config attribute ids, followed for each one + // of the configs, their values. + memcpy(buffer, kConfigAttributes, kConfigAttributesLen * kGLuintSize); + + for (int i = 0; i < mCount; ++i) { + memcpy(buffer + (i + 1) * kConfigAttributesLen, mConfigs[i]->mAttribValues, + kConfigAttributesLen * kGLuintSize); + } + return mCount; +}