am 8e9d7d55: Merge "Eliminate requireGlContext" into mnc-dev
* commit '8e9d7d55053094f5cc9ab8bcd5a0a9803ec40dfe': Eliminate requireGlContext
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include "Properties.h"
|
#include "Properties.h"
|
||||||
#include "renderstate/RenderState.h"
|
#include "renderstate/RenderState.h"
|
||||||
#include "ShadowTessellator.h"
|
#include "ShadowTessellator.h"
|
||||||
|
#include "utils/GLUtils.h"
|
||||||
|
|
||||||
#include <utils/Log.h>
|
#include <utils/Log.h>
|
||||||
#include <utils/String8.h>
|
#include <utils/String8.h>
|
||||||
@@ -276,6 +277,9 @@ void Caches::flush(FlushMode mode) {
|
|||||||
|
|
||||||
clearGarbage();
|
clearGarbage();
|
||||||
glFinish();
|
glFinish();
|
||||||
|
// Errors during cleanup should be considered non-fatal, dump them and
|
||||||
|
// and move on. TODO: All errors or just errors like bad surface?
|
||||||
|
GLUtils::dumpGLErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
@@ -119,7 +119,6 @@ void DeferredLayerUpdater::doUpdateTexImage() {
|
|||||||
|
|
||||||
void DeferredLayerUpdater::detachSurfaceTexture() {
|
void DeferredLayerUpdater::detachSurfaceTexture() {
|
||||||
if (mSurfaceTexture.get()) {
|
if (mSurfaceTexture.get()) {
|
||||||
mRenderThread.eglManager().requireGlContext();
|
|
||||||
status_t err = mSurfaceTexture->detachFromContext();
|
status_t err = mSurfaceTexture->detachFromContext();
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
// TODO: Elevate to fatal exception
|
// TODO: Elevate to fatal exception
|
||||||
|
|||||||
@@ -169,7 +169,8 @@ void RenderState::debugOverdraw(bool enable, bool clear) {
|
|||||||
|
|
||||||
void RenderState::requireGLContext() {
|
void RenderState::requireGLContext() {
|
||||||
assertOnGLThread();
|
assertOnGLThread();
|
||||||
mRenderThread.eglManager().requireGlContext();
|
LOG_ALWAYS_FATAL_IF(!mRenderThread.eglManager().hasEglContext(),
|
||||||
|
"No GL context!");
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderState::assertOnGLThread() {
|
void RenderState::assertOnGLThread() {
|
||||||
|
|||||||
@@ -262,8 +262,6 @@ void CanvasContext::draw() {
|
|||||||
|
|
||||||
if (drew) {
|
if (drew) {
|
||||||
swapBuffers(dirty, width, height);
|
swapBuffers(dirty, width, height);
|
||||||
} else {
|
|
||||||
mEglManager.cancelFrame();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Use a fence for real completion?
|
// TODO: Use a fence for real completion?
|
||||||
@@ -297,7 +295,6 @@ void CanvasContext::invokeFunctor(RenderThread& thread, Functor* functor) {
|
|||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
|
DrawGlInfo::Mode mode = DrawGlInfo::kModeProcessNoContext;
|
||||||
if (thread.eglManager().hasEglContext()) {
|
if (thread.eglManager().hasEglContext()) {
|
||||||
thread.eglManager().requireGlContext();
|
|
||||||
mode = DrawGlInfo::kModeProcess;
|
mode = DrawGlInfo::kModeProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +315,6 @@ static void destroyPrefetechedNode(RenderNode* node) {
|
|||||||
|
|
||||||
void CanvasContext::freePrefetechedLayers() {
|
void CanvasContext::freePrefetechedLayers() {
|
||||||
if (mPrefetechedLayers.size()) {
|
if (mPrefetechedLayers.size()) {
|
||||||
requireGlContext();
|
|
||||||
std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
|
std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
|
||||||
mPrefetechedLayers.clear();
|
mPrefetechedLayers.clear();
|
||||||
}
|
}
|
||||||
@@ -329,7 +325,6 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
|||||||
if (!mEglManager.hasEglContext() || !mCanvas) {
|
if (!mEglManager.hasEglContext() || !mCanvas) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
requireGlContext();
|
|
||||||
// buildLayer() will leave the tree in an unknown state, so we must stop drawing
|
// buildLayer() will leave the tree in an unknown state, so we must stop drawing
|
||||||
stopDrawing();
|
stopDrawing();
|
||||||
|
|
||||||
@@ -352,7 +347,6 @@ void CanvasContext::buildLayer(RenderNode* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
|
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
|
||||||
requireGlContext();
|
|
||||||
layer->apply();
|
layer->apply();
|
||||||
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
|
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
|
||||||
}
|
}
|
||||||
@@ -360,7 +354,6 @@ bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap)
|
|||||||
void CanvasContext::destroyHardwareResources() {
|
void CanvasContext::destroyHardwareResources() {
|
||||||
stopDrawing();
|
stopDrawing();
|
||||||
if (mEglManager.hasEglContext()) {
|
if (mEglManager.hasEglContext()) {
|
||||||
requireGlContext();
|
|
||||||
freePrefetechedLayers();
|
freePrefetechedLayers();
|
||||||
mRootRenderNode->destroyHardwareResources();
|
mRootRenderNode->destroyHardwareResources();
|
||||||
Caches::getInstance().flush(Caches::kFlushMode_Layers);
|
Caches::getInstance().flush(Caches::kFlushMode_Layers);
|
||||||
@@ -372,7 +365,6 @@ void CanvasContext::trimMemory(RenderThread& thread, int level) {
|
|||||||
if (!thread.eglManager().hasEglContext()) return;
|
if (!thread.eglManager().hasEglContext()) return;
|
||||||
|
|
||||||
ATRACE_CALL();
|
ATRACE_CALL();
|
||||||
thread.eglManager().requireGlContext();
|
|
||||||
if (level >= TRIM_MEMORY_COMPLETE) {
|
if (level >= TRIM_MEMORY_COMPLETE) {
|
||||||
Caches::getInstance().flush(Caches::kFlushMode_Full);
|
Caches::getInstance().flush(Caches::kFlushMode_Full);
|
||||||
thread.eglManager().destroy();
|
thread.eglManager().destroy();
|
||||||
@@ -382,7 +374,8 @@ void CanvasContext::trimMemory(RenderThread& thread, int level) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::runWithGlContext(RenderTask* task) {
|
void CanvasContext::runWithGlContext(RenderTask* task) {
|
||||||
requireGlContext();
|
LOG_ALWAYS_FATAL_IF(!mEglManager.hasEglContext(),
|
||||||
|
"GL context not initialized!");
|
||||||
task->run();
|
task->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,10 +384,6 @@ Layer* CanvasContext::createTextureLayer() {
|
|||||||
return LayerRenderer::createTextureLayer(mRenderThread.renderState());
|
return LayerRenderer::createTextureLayer(mRenderThread.renderState());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasContext::requireGlContext() {
|
|
||||||
mEglManager.requireGlContext();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasContext::setTextureAtlas(RenderThread& thread,
|
void CanvasContext::setTextureAtlas(RenderThread& thread,
|
||||||
const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) {
|
const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize) {
|
||||||
thread.eglManager().setTextureAtlas(buffer, map, mapSize);
|
thread.eglManager().setTextureAtlas(buffer, map, mapSize);
|
||||||
|
|||||||
@@ -122,8 +122,6 @@ private:
|
|||||||
void swapBuffers(const SkRect& dirty, EGLint width, EGLint height);
|
void swapBuffers(const SkRect& dirty, EGLint width, EGLint height);
|
||||||
void requireSurface();
|
void requireSurface();
|
||||||
|
|
||||||
void requireGlContext();
|
|
||||||
|
|
||||||
void freePrefetechedLayers();
|
void freePrefetechedLayers();
|
||||||
|
|
||||||
RenderThread& mRenderThread;
|
RenderThread& mRenderThread;
|
||||||
|
|||||||
@@ -78,8 +78,7 @@ EglManager::EglManager(RenderThread& thread)
|
|||||||
, mAllowPreserveBuffer(load_dirty_regions_property())
|
, mAllowPreserveBuffer(load_dirty_regions_property())
|
||||||
, mCurrentSurface(EGL_NO_SURFACE)
|
, mCurrentSurface(EGL_NO_SURFACE)
|
||||||
, mAtlasMap(nullptr)
|
, mAtlasMap(nullptr)
|
||||||
, mAtlasMapSize(0)
|
, mAtlasMapSize(0) {
|
||||||
, mInFrame(false) {
|
|
||||||
mCanSetPreserveBuffer = mAllowPreserveBuffer;
|
mCanSetPreserveBuffer = mAllowPreserveBuffer;
|
||||||
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
|
ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false");
|
||||||
}
|
}
|
||||||
@@ -101,7 +100,8 @@ void EglManager::initialize() {
|
|||||||
|
|
||||||
loadConfig();
|
loadConfig();
|
||||||
createContext();
|
createContext();
|
||||||
usePBufferSurface();
|
createPBufferSurface();
|
||||||
|
makeCurrent(mPBufferSurface);
|
||||||
mRenderThread.renderState().onGLContextCreated();
|
mRenderThread.renderState().onGLContextCreated();
|
||||||
initAtlas();
|
initAtlas();
|
||||||
}
|
}
|
||||||
@@ -110,17 +110,6 @@ bool EglManager::hasEglContext() {
|
|||||||
return mEglDisplay != EGL_NO_DISPLAY;
|
return mEglDisplay != EGL_NO_DISPLAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EglManager::requireGlContext() {
|
|
||||||
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY, "No EGL context");
|
|
||||||
|
|
||||||
if (!mInFrame) {
|
|
||||||
// We can't be certain about the state of the current surface (whether
|
|
||||||
// or not it is destroyed, for example), so err on the side of using
|
|
||||||
// the pbuffer surface which we fully control
|
|
||||||
usePBufferSurface();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EglManager::loadConfig() {
|
void EglManager::loadConfig() {
|
||||||
EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
|
EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0;
|
||||||
EGLint attribs[] = {
|
EGLint attribs[] = {
|
||||||
@@ -173,7 +162,6 @@ void EglManager::setTextureAtlas(const sp<GraphicBuffer>& buffer,
|
|||||||
mAtlasMapSize = mapSize;
|
mAtlasMapSize = mapSize;
|
||||||
|
|
||||||
if (hasEglContext()) {
|
if (hasEglContext()) {
|
||||||
usePBufferSurface();
|
|
||||||
initAtlas();
|
initAtlas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -185,7 +173,7 @@ void EglManager::initAtlas() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EglManager::usePBufferSurface() {
|
void EglManager::createPBufferSurface() {
|
||||||
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
|
LOG_ALWAYS_FATAL_IF(mEglDisplay == EGL_NO_DISPLAY,
|
||||||
"usePBufferSurface() called on uninitialized GlobalContext!");
|
"usePBufferSurface() called on uninitialized GlobalContext!");
|
||||||
|
|
||||||
@@ -193,7 +181,6 @@ void EglManager::usePBufferSurface() {
|
|||||||
EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
|
EGLint attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
|
||||||
mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
|
mPBufferSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, attribs);
|
||||||
}
|
}
|
||||||
makeCurrent(mPBufferSurface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
|
EGLSurface EglManager::createSurface(EGLNativeWindowType window) {
|
||||||
@@ -217,8 +204,6 @@ void EglManager::destroySurface(EGLSurface surface) {
|
|||||||
void EglManager::destroy() {
|
void EglManager::destroy() {
|
||||||
if (mEglDisplay == EGL_NO_DISPLAY) return;
|
if (mEglDisplay == EGL_NO_DISPLAY) return;
|
||||||
|
|
||||||
usePBufferSurface();
|
|
||||||
|
|
||||||
mRenderThread.renderState().onGLContextDestroyed();
|
mRenderThread.renderState().onGLContextDestroyed();
|
||||||
eglDestroyContext(mEglDisplay, mEglContext);
|
eglDestroyContext(mEglDisplay, mEglContext);
|
||||||
eglDestroySurface(mEglDisplay, mPBufferSurface);
|
eglDestroySurface(mEglDisplay, mPBufferSurface);
|
||||||
@@ -236,11 +221,10 @@ bool EglManager::makeCurrent(EGLSurface surface) {
|
|||||||
if (isCurrent(surface)) return false;
|
if (isCurrent(surface)) return false;
|
||||||
|
|
||||||
if (surface == EGL_NO_SURFACE) {
|
if (surface == EGL_NO_SURFACE) {
|
||||||
// If we are setting EGL_NO_SURFACE we don't care about any of the potential
|
// Ensure we always have a valid surface & context
|
||||||
// return errors, which would only happen if mEglDisplay had already been
|
surface = mPBufferSurface;
|
||||||
// destroyed in which case the current context is already NO_CONTEXT
|
}
|
||||||
eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
|
||||||
} else if (!eglMakeCurrent(mEglDisplay, surface, surface, mEglContext)) {
|
|
||||||
LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",
|
LOG_ALWAYS_FATAL("Failed to make current on surface %p, error=%s",
|
||||||
(void*)surface, egl_error_str());
|
(void*)surface, egl_error_str());
|
||||||
}
|
}
|
||||||
@@ -259,12 +243,10 @@ void EglManager::beginFrame(EGLSurface surface, EGLint* width, EGLint* height) {
|
|||||||
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
|
eglQuerySurface(mEglDisplay, surface, EGL_HEIGHT, height);
|
||||||
}
|
}
|
||||||
eglBeginFrame(mEglDisplay, surface);
|
eglBeginFrame(mEglDisplay, surface);
|
||||||
mInFrame = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EglManager::swapBuffers(EGLSurface surface, const SkRect& dirty,
|
bool EglManager::swapBuffers(EGLSurface surface, const SkRect& dirty,
|
||||||
EGLint width, EGLint height) {
|
EGLint width, EGLint height) {
|
||||||
mInFrame = false;
|
|
||||||
|
|
||||||
#if WAIT_FOR_GPU_COMPLETION
|
#if WAIT_FOR_GPU_COMPLETION
|
||||||
{
|
{
|
||||||
@@ -328,10 +310,6 @@ void EglManager::fence() {
|
|||||||
eglDestroySyncKHR(mEglDisplay, fence);
|
eglDestroySyncKHR(mEglDisplay, fence);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EglManager::cancelFrame() {
|
|
||||||
mInFrame = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
|
bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) {
|
||||||
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
|
if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false;
|
||||||
|
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ public:
|
|||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
bool hasEglContext();
|
bool hasEglContext();
|
||||||
void requireGlContext();
|
|
||||||
|
|
||||||
void usePBufferSurface();
|
|
||||||
EGLSurface createSurface(EGLNativeWindowType window);
|
EGLSurface createSurface(EGLNativeWindowType window);
|
||||||
void destroySurface(EGLSurface surface);
|
void destroySurface(EGLSurface surface);
|
||||||
|
|
||||||
@@ -49,7 +47,6 @@ public:
|
|||||||
bool makeCurrent(EGLSurface surface);
|
bool makeCurrent(EGLSurface surface);
|
||||||
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
|
void beginFrame(EGLSurface surface, EGLint* width, EGLint* height);
|
||||||
bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height);
|
bool swapBuffers(EGLSurface surface, const SkRect& dirty, EGLint width, EGLint height);
|
||||||
void cancelFrame();
|
|
||||||
|
|
||||||
// Returns true iff the surface is now preserving buffers.
|
// Returns true iff the surface is now preserving buffers.
|
||||||
bool setPreserveBuffer(EGLSurface surface, bool preserve);
|
bool setPreserveBuffer(EGLSurface surface, bool preserve);
|
||||||
@@ -65,6 +62,7 @@ private:
|
|||||||
// EglContext is never destroyed, method is purposely not implemented
|
// EglContext is never destroyed, method is purposely not implemented
|
||||||
~EglManager();
|
~EglManager();
|
||||||
|
|
||||||
|
void createPBufferSurface();
|
||||||
void loadConfig();
|
void loadConfig();
|
||||||
void createContext();
|
void createContext();
|
||||||
void initAtlas();
|
void initAtlas();
|
||||||
@@ -84,12 +82,6 @@ private:
|
|||||||
sp<GraphicBuffer> mAtlasBuffer;
|
sp<GraphicBuffer> mAtlasBuffer;
|
||||||
int64_t* mAtlasMap;
|
int64_t* mAtlasMap;
|
||||||
size_t mAtlasMapSize;
|
size_t mAtlasMapSize;
|
||||||
|
|
||||||
// Whether or not we are in the middle of drawing a frame. This is used
|
|
||||||
// to avoid switching surfaces mid-frame if requireGlContext() is called
|
|
||||||
// TODO: Need to be better about surface/context management so that this isn't
|
|
||||||
// necessary
|
|
||||||
bool mInFrame;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace renderthread */
|
} /* namespace renderthread */
|
||||||
|
|||||||
Reference in New Issue
Block a user