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 */ 163b20251a355c88193c439f928a84ae69483fb488John Reck#include "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) 260e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck , mCaches(NULL) 273b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportWidth(0) 283b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportHeight(0) 293b20251a355c88193c439f928a84ae69483fb488John Reck , mFramebuffer(0) { 300e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mThreadId = pthread_self(); 313b20251a355c88193c439f928a84ae69483fb488John Reck} 323b20251a355c88193c439f928a84ae69483fb488John Reck 333b20251a355c88193c439f928a84ae69483fb488John ReckRenderState::~RenderState() { 343b20251a355c88193c439f928a84ae69483fb488John Reck} 353b20251a355c88193c439f928a84ae69483fb488John Reck 363b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::onGLContextCreated() { 373b20251a355c88193c439f928a84ae69483fb488John Reck // This is delayed because the first access of Caches makes GL calls 383b20251a355c88193c439f928a84ae69483fb488John Reck mCaches = &Caches::getInstance(); 393b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->init(); 4017035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck mCaches->setRenderState(this); 41ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mCaches->textureCache.setAssetAtlas(&mAssetAtlas); 423b20251a355c88193c439f928a84ae69483fb488John Reck} 433b20251a355c88193c439f928a84ae69483fb488John Reck 4457998017ff137f7d4ec33df21b6596141f8c4547John Reckstatic void layerLostGlContext(Layer* layer) { 4557998017ff137f7d4ec33df21b6596141f8c4547John Reck layer->onGlContextLost(); 4657998017ff137f7d4ec33df21b6596141f8c4547John Reck} 4757998017ff137f7d4ec33df21b6596141f8c4547John Reck 481d4774233304c484673e2af2c1de2ab41021c979Chris Craikvoid RenderState::onGLContextDestroyed() { 4921029ef131d6a98862ae6faf3305bee2872e9c5fChris Craik/* 50bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik size_t size = mActiveLayers.size(); 51bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik if (CC_UNLIKELY(size != 0)) { 52bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Crashing, have %d contexts and %d layers at context destruction. isempty %d", 53bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik mRegisteredContexts.size(), size, mActiveLayers.empty()); 5417035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck mCaches->dumpMemoryUsage(); 55443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck for (std::set<renderthread::CanvasContext*>::iterator cit = mRegisteredContexts.begin(); 56443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck cit != mRegisteredContexts.end(); cit++) { 57443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck renderthread::CanvasContext* context = *cit; 58bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Context: %p (root = %p)", context, context->mRootRenderNode.get()); 59bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE(" Prefeteched layers: %zu", context->mPrefetechedLayers.size()); 60443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck for (std::set<RenderNode*>::iterator pit = context->mPrefetechedLayers.begin(); 61443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck pit != context->mPrefetechedLayers.end(); pit++) { 62443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck (*pit)->debugDumpLayers(" "); 63443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 64443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck context->mRootRenderNode->debugDumpLayers(" "); 65443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck } 66599e254ea33231b1809466ae765dbee53dc4685cChris Craik 67bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik 68bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik if (mActiveLayers.begin() == mActiveLayers.end()) { 69bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("set has become empty. wat."); 70bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik } 71599e254ea33231b1809466ae765dbee53dc4685cChris Craik for (std::set<const Layer*>::iterator lit = mActiveLayers.begin(); 72599e254ea33231b1809466ae765dbee53dc4685cChris Craik lit != mActiveLayers.end(); lit++) { 73599e254ea33231b1809466ae765dbee53dc4685cChris Craik const Layer* layer = *(lit); 74bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik ALOGE("Layer %p, state %d, texlayer %d, fbo %d, buildlayered %d", 75bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik layer, layer->state, layer->isTextureLayer(), layer->getFbo(), layer->wasBuildLayered); 76599e254ea33231b1809466ae765dbee53dc4685cChris Craik } 77bfd1cd620991ac2fa9202fdce6c00ec47d071935Chris Craik LOG_ALWAYS_FATAL("%d layers have survived gl context destruction", size); 7817035b0211a3c9d45ea46a99217a6acbe76e8fbeJohn Reck } 7921029ef131d6a98862ae6faf3305bee2872e9c5fChris Craik*/ 8057998017ff137f7d4ec33df21b6596141f8c4547John Reck std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext); 81ebd52610cfeff6e557fde284a7e1efc5e6438285John Reck mAssetAtlas.terminate(); 821d4774233304c484673e2af2c1de2ab41021c979Chris Craik} 831d4774233304c484673e2af2c1de2ab41021c979Chris Craik 843b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::setViewport(GLsizei width, GLsizei height) { 853b20251a355c88193c439f928a84ae69483fb488John Reck mViewportWidth = width; 863b20251a355c88193c439f928a84ae69483fb488John Reck mViewportHeight = height; 873b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 883b20251a355c88193c439f928a84ae69483fb488John Reck} 893b20251a355c88193c439f928a84ae69483fb488John Reck 903b20251a355c88193c439f928a84ae69483fb488John Reck 913b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { 923b20251a355c88193c439f928a84ae69483fb488John Reck *outWidth = mViewportWidth; 933b20251a355c88193c439f928a84ae69483fb488John Reck *outHeight = mViewportHeight; 943b20251a355c88193c439f928a84ae69483fb488John Reck} 953b20251a355c88193c439f928a84ae69483fb488John Reck 963b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::bindFramebuffer(GLuint fbo) { 973b20251a355c88193c439f928a84ae69483fb488John Reck if (mFramebuffer != fbo) { 983b20251a355c88193c439f928a84ae69483fb488John Reck mFramebuffer = fbo; 993b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1003b20251a355c88193c439f928a84ae69483fb488John Reck } 1013b20251a355c88193c439f928a84ae69483fb488John Reck} 1023b20251a355c88193c439f928a84ae69483fb488John Reck 1033b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { 1043b20251a355c88193c439f928a84ae69483fb488John Reck interruptForFunctorInvoke(); 1053b20251a355c88193c439f928a84ae69483fb488John Reck (*functor)(mode, info); 1063b20251a355c88193c439f928a84ae69483fb488John Reck resumeFromFunctorInvoke(); 1073b20251a355c88193c439f928a84ae69483fb488John Reck} 1083b20251a355c88193c439f928a84ae69483fb488John Reck 1093b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::interruptForFunctorInvoke() { 1103b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->currentProgram) { 1113b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->currentProgram->isInUse()) { 1123b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->currentProgram->remove(); 1133b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->currentProgram = NULL; 1143b20251a355c88193c439f928a84ae69483fb488John Reck } 1153b20251a355c88193c439f928a84ae69483fb488John Reck } 1163b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetActiveTexture(); 1173b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->unbindMeshBuffer(); 1183b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->unbindIndicesBuffer(); 1193b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetVertexPointers(); 1203b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->disableTexCoordsVertexArray(); 1213b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 1223b20251a355c88193c439f928a84ae69483fb488John Reck} 1233b20251a355c88193c439f928a84ae69483fb488John Reck 1243b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::resumeFromFunctorInvoke() { 1253b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1263b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1273b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 1283b20251a355c88193c439f928a84ae69483fb488John Reck 1293b20251a355c88193c439f928a84ae69483fb488John Reck glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 1303b20251a355c88193c439f928a84ae69483fb488John Reck 1313b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->scissorEnabled = glIsEnabled(GL_SCISSOR_TEST); 1323b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->enableScissor(); 1333b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetScissor(); 1343b20251a355c88193c439f928a84ae69483fb488John Reck 1353b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->activeTexture(0); 1363b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->resetBoundTextures(); 1373b20251a355c88193c439f928a84ae69483fb488John Reck 1383b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->blend = true; 1393b20251a355c88193c439f928a84ae69483fb488John Reck glEnable(GL_BLEND); 1403b20251a355c88193c439f928a84ae69483fb488John Reck glBlendFunc(mCaches->lastSrcMode, mCaches->lastDstMode); 1413b20251a355c88193c439f928a84ae69483fb488John Reck glBlendEquation(GL_FUNC_ADD); 1423b20251a355c88193c439f928a84ae69483fb488John Reck} 1433b20251a355c88193c439f928a84ae69483fb488John Reck 1443b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::debugOverdraw(bool enable, bool clear) { 1453b20251a355c88193c439f928a84ae69483fb488John Reck if (mCaches->debugOverdraw && mFramebuffer == 0) { 1463b20251a355c88193c439f928a84ae69483fb488John Reck if (clear) { 1473b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->disableScissor(); 1483b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->stencil.clear(); 1493b20251a355c88193c439f928a84ae69483fb488John Reck } 1503b20251a355c88193c439f928a84ae69483fb488John Reck if (enable) { 1513b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->stencil.enableDebugWrite(); 1523b20251a355c88193c439f928a84ae69483fb488John Reck } else { 1533b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->stencil.disable(); 1543b20251a355c88193c439f928a84ae69483fb488John Reck } 1553b20251a355c88193c439f928a84ae69483fb488John Reck } 1563b20251a355c88193c439f928a84ae69483fb488John Reck} 1573b20251a355c88193c439f928a84ae69483fb488John Reck 1580e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::requireGLContext() { 1590e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck assertOnGLThread(); 1600e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mRenderThread.eglManager().requireGlContext(); 1610e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 1620e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1630e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::assertOnGLThread() { 1640e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck pthread_t curr = pthread_self(); 1650e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck LOG_ALWAYS_FATAL_IF(!pthread_equal(mThreadId, curr), "Wrong thread!"); 1660e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 1670e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1680e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1690e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckclass DecStrongTask : public renderthread::RenderTask { 1700e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckpublic: 1710e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} 1720e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1730e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck virtual void run() { 1740e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mObject->decStrong(0); 1750e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mObject = 0; 1760e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck delete this; 1770e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck } 1780e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1790e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckprivate: 1800e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck VirtualLightRefBase* mObject; 1810e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck}; 1820e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1830e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::postDecStrong(VirtualLightRefBase* object) { 1840e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mRenderThread.queue(new DecStrongTask(object)); 1850e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 1860e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 1873b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace uirenderer */ 1883b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace android */ 189