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