RenderState.cpp revision ff5c8e8097e3eff910632a568195b798798ccccc
13b20251a355c88193c439f928a84ae69483fb488John Reck/* 23b20251a355c88193c439f928a84ae69483fb488John Reck * Copyright (C) 2014 The Android Open Source Project 33b20251a355c88193c439f928a84ae69483fb488John Reck * 43b20251a355c88193c439f928a84ae69483fb488John Reck * Licensed under the Apache License, Version 2.0 (the "License"); 53b20251a355c88193c439f928a84ae69483fb488John Reck * you may not use this file except in compliance with the License. 63b20251a355c88193c439f928a84ae69483fb488John Reck * You may obtain a copy of the License at 73b20251a355c88193c439f928a84ae69483fb488John Reck * 83b20251a355c88193c439f928a84ae69483fb488John Reck * http://www.apache.org/licenses/LICENSE-2.0 93b20251a355c88193c439f928a84ae69483fb488John Reck * 103b20251a355c88193c439f928a84ae69483fb488John Reck * Unless required by applicable law or agreed to in writing, software 113b20251a355c88193c439f928a84ae69483fb488John Reck * distributed under the License is distributed on an "AS IS" BASIS, 123b20251a355c88193c439f928a84ae69483fb488John Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133b20251a355c88193c439f928a84ae69483fb488John Reck * See the License for the specific language governing permissions and 143b20251a355c88193c439f928a84ae69483fb488John Reck * limitations under the License. 153b20251a355c88193c439f928a84ae69483fb488John Reck */ 1696a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "renderstate/RenderState.h" 173b20251a355c88193c439f928a84ae69483fb488John Reck 18443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck#include "renderthread/CanvasContext.h" 190e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck#include "renderthread/EglManager.h" 20443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck 213b20251a355c88193c439f928a84ae69483fb488John Recknamespace android { 223b20251a355c88193c439f928a84ae69483fb488John Recknamespace uirenderer { 233b20251a355c88193c439f928a84ae69483fb488John Reck 240e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John ReckRenderState::RenderState(renderthread::RenderThread& thread) 250e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck : mRenderThread(thread) 26d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik , mCaches(nullptr) 2796a5c4c7bab6718524de7253da8309143ab48befChris Craik , mMeshState(nullptr) 2896a5c4c7bab6718524de7253da8309143ab48befChris Craik , mScissor(nullptr) 2996a5c4c7bab6718524de7253da8309143ab48befChris Craik , mStencil(nullptr) 303b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportWidth(0) 313b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportHeight(0) 323b20251a355c88193c439f928a84ae69483fb488John Reck , mFramebuffer(0) { 330e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mThreadId = pthread_self(); 343b20251a355c88193c439f928a84ae69483fb488John Reck} 353b20251a355c88193c439f928a84ae69483fb488John Reck 363b20251a355c88193c439f928a84ae69483fb488John ReckRenderState::~RenderState() { 3796a5c4c7bab6718524de7253da8309143ab48befChris Craik LOG_ALWAYS_FATAL_IF(mMeshState || mScissor || mStencil, 3896a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 393b20251a355c88193c439f928a84ae69483fb488John Reck} 403b20251a355c88193c439f928a84ae69483fb488John Reck 413b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::onGLContextCreated() { 4296a5c4c7bab6718524de7253da8309143ab48befChris Craik LOG_ALWAYS_FATAL_IF(mMeshState || mScissor || mStencil, 4396a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 4496a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = new MeshState(); 4596a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = new Scissor(); 4696a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = new Stencil(); 4796a5c4c7bab6718524de7253da8309143ab48befChris Craik 483b20251a355c88193c439f928a84ae69483fb488John Reck // This is delayed because the first access of Caches makes GL calls 49ff5c8e8097e3eff910632a568195b798798cccccChris Craik if (!mCaches) { 50ff5c8e8097e3eff910632a568195b798798cccccChris Craik mCaches = &Caches::createInstance(*this); 51ff5c8e8097e3eff910632a568195b798798cccccChris Craik } 523b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->init(); 53ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mCaches->textureCache.setAssetAtlas(&mAssetAtlas); 543b20251a355c88193c439f928a84ae69483fb488John Reck} 553b20251a355c88193c439f928a84ae69483fb488John Reck 5657998017ff137f7d4ec33df21b6596141f8c4547John Reckstatic void layerLostGlContext(Layer* layer) { 5757998017ff137f7d4ec33df21b6596141f8c4547John Reck layer->onGlContextLost(); 5857998017ff137f7d4ec33df21b6596141f8c4547John Reck} 5957998017ff137f7d4ec33df21b6596141f8c4547John Reck 601d4774233304c484673e2af2c1de2ab41021c979Chris Craikvoid RenderState::onGLContextDestroyed() { 6121029ef131d6a98862ae6faf3305bee2872e9c5fChris Craik/* 62bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik size_t size = mActiveLayers.size(); 63bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik if (CC_UNLIKELY(size != 0)) { 64bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d", 65bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik mRegisteredContexts.size(), size, mActiveLayers.empty()); 6617035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck mCaches->dumpMemoryUsage(); 67443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin(); 68443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck cit != mRegisteredContexts.end(); cit++) { 69443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck renderthread::CanvasContext* context = *cit; 70bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get()); 71bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size()); 72443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin(); 73443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck pit != context->mPrefetechedLayers.end(); pit++) { 74443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck (*pit)->debugDumpLayers(" "); 75443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 76443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck context->mRootRenderNode->debugDumpLayers(" "); 77443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 78599e254ea33231b1809466ae765dbee53dc4685cChris Craik 79bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik 80bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik if (mActiveLayers.begin() == mActiveLayers.end()) { 81bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("set has become empty. wat."); 82bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik } 83599e254ea33231b1809466ae765dbee53dc4685cChris Craik for (std::set<const Layer*>::iterator lit = mActiveLayers.begin(); 84599e254ea33231b1809466ae765dbee53dc4685cChris Craik lit != mActiveLayers.end(); lit++) { 85599e254ea33231b1809466ae765dbee53dc4685cChris Craik const Layer* layer = *(lit); 86bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d", 87bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered); 88599e254ea33231b1809466ae765dbee53dc4685cChris Craik } 89bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size); 9017035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck } 9121029ef131d6a98862ae6faf3305bee2872e9c5fChris Craik*/ 9249bc4acfadf9c5b1e520217278ccb38010d38c89John Reck 9396a5c4c7bab6718524de7253da8309143ab48befChris Craik // TODO: reset all cached state in state objects 9457998017ff137f7d4ec33df21b6596141f8c4547John Reck std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext); 95ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mAssetAtlas.terminate(); 9696a5c4c7bab6718524de7253da8309143ab48befChris Craik 9796a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mMeshState; 9896a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = nullptr; 9996a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mScissor; 10096a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = nullptr; 10196a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mStencil; 10296a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = nullptr; 1031d4774233304c484673e2af2c1de2ab41021c979Chris Craik} 1041d4774233304c484673e2af2c1de2ab41021c979Chris Craik 1053b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::setViewport(GLsizei width, GLsizei height) { 1063b20251a355c88193c439f928a84ae69483fb488John Reck mViewportWidth = width; 1073b20251a355c88193c439f928a84ae69483fb488John Reck mViewportHeight = height; 1083b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1093b20251a355c88193c439f928a84ae69483fb488John Reck} 1103b20251a355c88193c439f928a84ae69483fb488John Reck 1113b20251a355c88193c439f928a84ae69483fb488John Reck 1123b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { 1133b20251a355c88193c439f928a84ae69483fb488John Reck *outWidth = mViewportWidth; 1143b20251a355c88193c439f928a84ae69483fb488John Reck *outHeight = mViewportHeight; 1153b20251a355c88193c439f928a84ae69483fb488John Reck} 1163b20251a355c88193c439f928a84ae69483fb488John Reck 1173b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::bindFramebuffer(GLuint fbo) { 1183b20251a355c88193c439f928a84ae69483fb488John Reck if (mFramebuffer != fbo) { 1193b20251a355c88193c439f928a84ae69483fb488John Reck mFramebuffer = fbo; 1203b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1213b20251a355c88193c439f928a84ae69483fb488John Reck } 1223b20251a355c88193c439f928a84ae69483fb488John Reck} 1233b20251a355c88193c439f928a84ae69483fb488John Reck 1243b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { 1253b20251a355c88193c439f928a84ae69483fb488John Reck interruptForFunctorInvoke(); 1263b20251a355c88193c439f928a84ae69483fb488John Reck (*functor)(mode, info); 1273b20251a355c88193c439f928a84ae69483fb488John Reck resumeFromFunctorInvoke(); 1283b20251a355c88193c439f928a84ae69483fb488John Reck} 1293b20251a355c88193c439f928a84ae69483fb488John Reck 1303b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::interruptForFunctorInvoke() { 1313b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->currentProgram) { 1323b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->currentProgram->isInUse()) { 1333b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->currentProgram->remove(); 134d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mCaches->currentProgram = nullptr; 1353b20251a355c88193c439f928a84ae69483fb488John Reck } 1363b20251a355c88193c439f928a84ae69483fb488John Reck } 1373b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetActiveTexture(); 13896a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindMeshBuffer(); 13996a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindIndicesBuffer(); 14096a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().resetVertexPointers(); 14196a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().disableTexCoordsVertexArray(); 1423b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 1433b20251a355c88193c439f928a84ae69483fb488John Reck} 1443b20251a355c88193c439f928a84ae69483fb488John Reck 1453b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::resumeFromFunctorInvoke() { 1463b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1473b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1483b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 1493b20251a355c88193c439f928a84ae69483fb488John Reck 1503b20251a355c88193c439f928a84ae69483fb488John Reck glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 1513b20251a355c88193c439f928a84ae69483fb488John Reck 15265fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().invalidate(); 1533b20251a355c88193c439f928a84ae69483fb488John Reck 1543b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->activeTexture(0); 1553b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetBoundTextures(); 1563b20251a355c88193c439f928a84ae69483fb488John Reck 1573b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->blend = true; 1583b20251a355c88193c439f928a84ae69483fb488John Reck glEnable(GL_BLEND); 1593b20251a355c88193c439f928a84ae69483fb488John Reck glBlendFunc(mCaches->lastSrcMode, mCaches->lastDstMode); 1603b20251a355c88193c439f928a84ae69483fb488John Reck glBlendEquation(GL_FUNC_ADD); 1613b20251a355c88193c439f928a84ae69483fb488John Reck} 1623b20251a355c88193c439f928a84ae69483fb488John Reck 1633b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::debugOverdraw(bool enable, bool clear) { 1643b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->debugOverdraw && mFramebuffer == 0) { 1653b20251a355c88193c439f928a84ae69483fb488John Reck if (clear) { 16665fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().setEnabled(false); 16796a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().clear(); 1683b20251a355c88193c439f928a84ae69483fb488John Reck } 1693b20251a355c88193c439f928a84ae69483fb488John Reck if (enable) { 17096a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().enableDebugWrite(); 1713b20251a355c88193c439f928a84ae69483fb488John Reck } else { 17296a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().disable(); 1733b20251a355c88193c439f928a84ae69483fb488John Reck } 1743b20251a355c88193c439f928a84ae69483fb488John Reck } 1753b20251a355c88193c439f928a84ae69483fb488John Reck} 1763b20251a355c88193c439f928a84ae69483fb488John Reck 1770e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::requireGLContext() { 1780e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck assertOnGLThread(); 1790e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mRenderThread.eglManager().requireGlContext(); 1800e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 1810e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1820e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::assertOnGLThread() { 1830e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck pthread_t curr = pthread_self(); 1840e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!"); 1850e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 1860e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1870e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1880e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckclass DecStrongTask : public renderthread::RenderTask { 1890e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckpublic: 1900e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} 1910e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 192d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void run() override { 193d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject->decStrong(nullptr); 194d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject = nullptr; 1950e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck delete this; 1960e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck } 1970e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1980e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckprivate: 1990e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck VirtualLightRefBase* mObject; 2000e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck}; 2010e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2020e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::postDecStrong(VirtualLightRefBase* object) { 2030e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mRenderThread.queue(new DecStrongTask(object)); 2040e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 2050e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2063b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace uirenderer */ 2073b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace android */ 208