RenderState.cpp revision efb4b06493fe7b1604c762a448b13c7af2845a8d
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 */ 163e9999bd866fac71c72e6b484a9836c87c328a08sergeyv#include "DeferredLayerUpdater.h" 178cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel#include "GlLayer.h" 1845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel#include "VkLayer.h" 1938e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck#include <GpuMemoryTracker.h> 2096a5c4c7bab6718524de7253da8309143ab48befChris Craik#include "renderstate/RenderState.h" 213b20251a355c88193c439f928a84ae69483fb488John Reck 22443a714fa7c0dd07fee3527cc5bc3d3ca1fb7d44John Reck#include "renderthread/CanvasContext.h" 230e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck#include "renderthread/EglManager.h" 24117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik#include "utils/GLUtils.h" 259db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik#include <algorithm> 269db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik 273b20251a355c88193c439f928a84ae69483fb488John Recknamespace android { 283b20251a355c88193c439f928a84ae69483fb488John Recknamespace uirenderer { 293b20251a355c88193c439f928a84ae69483fb488John Reck 300e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John ReckRenderState::RenderState(renderthread::RenderThread& thread) 310e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck : mRenderThread(thread) 323b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportWidth(0) 333b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportHeight(0) 343b20251a355c88193c439f928a84ae69483fb488John Reck , mFramebuffer(0) { 350e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mThreadId = pthread_self(); 363b20251a355c88193c439f928a84ae69483fb488John Reck} 373b20251a355c88193c439f928a84ae69483fb488John Reck 383b20251a355c88193c439f928a84ae69483fb488John ReckRenderState::~RenderState() { 3944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 4096a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 413b20251a355c88193c439f928a84ae69483fb488John Reck} 423b20251a355c88193c439f928a84ae69483fb488John Reck 433b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::onGLContextCreated() { 4444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 4596a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 4645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextCreated(); 4738e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck 4844eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mBlend = new Blend(); 4996a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = new MeshState(); 5096a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = new Scissor(); 5196a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = new Stencil(); 5296a5c4c7bab6718524de7253da8309143ab48befChris Craik 533b20251a355c88193c439f928a84ae69483fb488John Reck // This is delayed because the first access of Caches makes GL calls 54ff5c8e8097e3eff910632a568195b798798cccccChris Craik if (!mCaches) { 55ff5c8e8097e3eff910632a568195b798798cccccChris Craik mCaches = &Caches::createInstance(*this); 56ff5c8e8097e3eff910632a568195b798798cccccChris Craik } 573b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->init(); 583b20251a355c88193c439f928a84ae69483fb488John Reck} 593b20251a355c88193c439f928a84ae69483fb488John Reck 6057998017ff137f7d4ec33df21b6596141f8c4547John Reckstatic void layerLostGlContext(Layer* layer) { 618cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL, 628cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel "layerLostGlContext on non GL layer"); 638cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel static_cast<GlLayer*>(layer)->onGlContextLost(); 6457998017ff137f7d4ec33df21b6596141f8c4547John Reck} 6557998017ff137f7d4ec33df21b6596141f8c4547John Reck 661d4774233304c484673e2af2c1de2ab41021c979Chris Craikvoid RenderState::onGLContextDestroyed() { 679fded232a9548a304e0145011df8849fba0dcda7Chris Craik mLayerPool.clear(); 689fded232a9548a304e0145011df8849fba0dcda7Chris Craik 6996a5c4c7bab6718524de7253da8309143ab48befChris Craik // TODO: reset all cached state in state objects 7057998017ff137f7d4ec33df21b6596141f8c4547John Reck std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext); 7196a5c4c7bab6718524de7253da8309143ab48befChris Craik 7244eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->terminate(); 7344eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik 7444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik delete mBlend; 7544eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mBlend = nullptr; 7696a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mMeshState; 7796a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = nullptr; 7896a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mScissor; 7996a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = nullptr; 8096a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mStencil; 8196a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = nullptr; 8238e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck 83c3f131696111a066d9efd9c7c3e37566a2a9fb89sergeyv destroyLayersInUpdater(); 8445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextDestroyed(); 8545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 8645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 8745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid RenderState::onVkContextCreated() { 8845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 8945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "State object lifecycle not managed correctly"); 9045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextCreated(); 9145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 9245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 9345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielstatic void layerDestroyedVkContext(Layer* layer) { 9445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::Vulkan, 9545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "layerLostVkContext on non Vulkan layer"); 9645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel static_cast<VkLayer*>(layer)->onVkContextDestroyed(); 9745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 9845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 9945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid RenderState::onVkContextDestroyed() { 10045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel mLayerPool.clear(); 10145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext); 10245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextDestroyed(); 10345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 10445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 10545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg DanielGrContext* RenderState::getGrContext() const { 10645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel return mRenderThread.getGrContext(); 1071d4774233304c484673e2af2c1de2ab41021c979Chris Craik} 1081d4774233304c484673e2af2c1de2ab41021c979Chris Craik 1099fded232a9548a304e0145011df8849fba0dcda7Chris Craikvoid RenderState::flush(Caches::FlushMode mode) { 1109fded232a9548a304e0145011df8849fba0dcda7Chris Craik switch (mode) { 1119fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Full: 1129fded232a9548a304e0145011df8849fba0dcda7Chris Craik // fall through 1139fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Moderate: 1149fded232a9548a304e0145011df8849fba0dcda7Chris Craik // fall through 1159fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Layers: 1169fded232a9548a304e0145011df8849fba0dcda7Chris Craik mLayerPool.clear(); 1179fded232a9548a304e0145011df8849fba0dcda7Chris Craik break; 1189fded232a9548a304e0145011df8849fba0dcda7Chris Craik } 1199fded232a9548a304e0145011df8849fba0dcda7Chris Craik mCaches->flush(mode); 1209fded232a9548a304e0145011df8849fba0dcda7Chris Craik} 1219fded232a9548a304e0145011df8849fba0dcda7Chris Craik 1223b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::setViewport(GLsizei width, GLsizei height) { 1233b20251a355c88193c439f928a84ae69483fb488John Reck mViewportWidth = width; 1243b20251a355c88193c439f928a84ae69483fb488John Reck mViewportHeight = height; 1253b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1263b20251a355c88193c439f928a84ae69483fb488John Reck} 1273b20251a355c88193c439f928a84ae69483fb488John Reck 1283b20251a355c88193c439f928a84ae69483fb488John Reck 1293b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { 1303b20251a355c88193c439f928a84ae69483fb488John Reck *outWidth = mViewportWidth; 1313b20251a355c88193c439f928a84ae69483fb488John Reck *outHeight = mViewportHeight; 1323b20251a355c88193c439f928a84ae69483fb488John Reck} 1333b20251a355c88193c439f928a84ae69483fb488John Reck 1343b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::bindFramebuffer(GLuint fbo) { 1353b20251a355c88193c439f928a84ae69483fb488John Reck if (mFramebuffer != fbo) { 1363b20251a355c88193c439f928a84ae69483fb488John Reck mFramebuffer = fbo; 1373b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1383b20251a355c88193c439f928a84ae69483fb488John Reck } 1393b20251a355c88193c439f928a84ae69483fb488John Reck} 1403b20251a355c88193c439f928a84ae69483fb488John Reck 1410b8d0677be2289bbc9e0b48c0878fb67d1cc0ebdJohn ReckGLuint RenderState::createFramebuffer() { 142818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik GLuint ret; 143818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glGenFramebuffers(1, &ret); 144818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik return ret; 145818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 146818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 147818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craikvoid RenderState::deleteFramebuffer(GLuint fbo) { 148818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik if (mFramebuffer == fbo) { 149818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // GL defines that deleting the currently bound FBO rebinds FBO 0. 150818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // Reflect this in our cached value. 151818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik mFramebuffer = 0; 152818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik } 153818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glDeleteFramebuffers(1, &fbo); 154818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 155818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 1563b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { 15795cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck if (mode == DrawGlInfo::kModeProcessNoContext) { 15895cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck // If there's no context we don't need to interrupt as there's 15995cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck // no gl state to save/restore 16095cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck (*functor)(mode, info); 16195cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck } else { 16295cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck interruptForFunctorInvoke(); 16395cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck (*functor)(mode, info); 16495cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck resumeFromFunctorInvoke(); 16595cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck } 1663b20251a355c88193c439f928a84ae69483fb488John Reck} 1673b20251a355c88193c439f928a84ae69483fb488John Reck 1683b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::interruptForFunctorInvoke() { 1696c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik mCaches->setProgram(nullptr); 17044eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().resetActiveTexture(); 17196a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindMeshBuffer(); 17296a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindIndicesBuffer(); 17396a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().resetVertexPointers(); 17496a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().disableTexCoordsVertexArray(); 1753b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 176253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy // TODO: We need a way to know whether the functor is sRGB aware (b/32072673) 177efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (mCaches->extensions().hasLinearBlending() && 178efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy mCaches->extensions().hasSRGBWriteControl()) { 179253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy glDisable(GL_FRAMEBUFFER_SRGB_EXT); 180253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy } 1813b20251a355c88193c439f928a84ae69483fb488John Reck} 1823b20251a355c88193c439f928a84ae69483fb488John Reck 1833b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::resumeFromFunctorInvoke() { 184efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (mCaches->extensions().hasLinearBlending() && 185efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy mCaches->extensions().hasSRGBWriteControl()) { 186253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy glEnable(GL_FRAMEBUFFER_SRGB_EXT); 187253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy } 188253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy 1893b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1903b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1913b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 1923b20251a355c88193c439f928a84ae69483fb488John Reck 1933b20251a355c88193c439f928a84ae69483fb488John Reck glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 1943b20251a355c88193c439f928a84ae69483fb488John Reck 19565fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().invalidate(); 19644eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik blend().invalidate(); 1973b20251a355c88193c439f928a84ae69483fb488John Reck 19844eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().activateTexture(0); 19944eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().resetBoundTextures(); 2003b20251a355c88193c439f928a84ae69483fb488John Reck} 2013b20251a355c88193c439f928a84ae69483fb488John Reck 2023b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::debugOverdraw(bool enable, bool clear) { 2032507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik if (Properties::debugOverdraw && mFramebuffer == 0) { 2043b20251a355c88193c439f928a84ae69483fb488John Reck if (clear) { 20565fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().setEnabled(false); 20696a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().clear(); 2073b20251a355c88193c439f928a84ae69483fb488John Reck } 2083b20251a355c88193c439f928a84ae69483fb488John Reck if (enable) { 20996a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().enableDebugWrite(); 2103b20251a355c88193c439f928a84ae69483fb488John Reck } else { 21196a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().disable(); 2123b20251a355c88193c439f928a84ae69483fb488John Reck } 2133b20251a355c88193c439f928a84ae69483fb488John Reck } 2143b20251a355c88193c439f928a84ae69483fb488John Reck} 2153b20251a355c88193c439f928a84ae69483fb488John Reck 2163e9999bd866fac71c72e6b484a9836c87c328a08sergeyvstatic void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) { 2173e9999bd866fac71c72e6b484a9836c87c328a08sergeyv layerUpdater->destroyLayer(); 2183e9999bd866fac71c72e6b484a9836c87c328a08sergeyv} 2193e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 2203e9999bd866fac71c72e6b484a9836c87c328a08sergeyvvoid RenderState::destroyLayersInUpdater() { 2213e9999bd866fac71c72e6b484a9836c87c328a08sergeyv std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater); 2223e9999bd866fac71c72e6b484a9836c87c328a08sergeyv} 2233e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 2240e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckclass DecStrongTask : public renderthread::RenderTask { 2250e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckpublic: 226c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} 2270e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 228d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void run() override { 229d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject->decStrong(nullptr); 230d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject = nullptr; 2310e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck delete this; 2320e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck } 2330e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2340e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckprivate: 2350e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck VirtualLightRefBase* mObject; 2360e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck}; 2370e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2380e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::postDecStrong(VirtualLightRefBase* object) { 239a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck if (pthread_equal(mThreadId, pthread_self())) { 240a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck object->decStrong(nullptr); 241a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck } else { 242a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck mRenderThread.queue(new DecStrongTask(object)); 243a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck } 2440e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 2450e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2466c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik/////////////////////////////////////////////////////////////////////////////// 2476c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik// Render 2486c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik/////////////////////////////////////////////////////////////////////////////// 2496c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 25012efe649d3f5df8e81f4b78179939c1d488673a0Chris Craikvoid RenderState::render(const Glop& glop, const Matrix4& orthoMatrix) { 2516c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik const Glop::Mesh& mesh = glop.mesh; 252ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const Glop::Mesh::Vertices& vertices = mesh.vertices; 253ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const Glop::Mesh::Indices& indices = mesh.indices; 2540519c810a56bded1284fcb2ae40f438878c6585fChris Craik const Glop::Fill& fill = glop.fill; 2556c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 256975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 2579372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 2580519c810a56bded1284fcb2ae40f438878c6585fChris Craik // --------------------------------------------- 2590519c810a56bded1284fcb2ae40f438878c6585fChris Craik // ---------- Program + uniform setup ---------- 2600519c810a56bded1284fcb2ae40f438878c6585fChris Craik // --------------------------------------------- 2610519c810a56bded1284fcb2ae40f438878c6585fChris Craik mCaches->setProgram(fill.program); 2626c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 2630519c810a56bded1284fcb2ae40f438878c6585fChris Craik if (fill.colorEnabled) { 2640519c810a56bded1284fcb2ae40f438878c6585fChris Craik fill.program->setColor(fill.color); 2650519c810a56bded1284fcb2ae40f438878c6585fChris Craik } 2666c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 26712efe649d3f5df8e81f4b78179939c1d488673a0Chris Craik fill.program->set(orthoMatrix, 2686c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glop.transform.modelView, 26953e51e4aa933f9603587e1780f446c18816bf9beChris Craik glop.transform.meshTransform(), 27053e51e4aa933f9603587e1780f446c18816bf9beChris Craik glop.transform.transformFlags & TransformFlags::OffsetByFudgeFactor); 271117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 2720519c810a56bded1284fcb2ae40f438878c6585fChris Craik // Color filter uniforms 273b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik if (fill.filterMode == ProgramDescription::ColorFilterMode::Blend) { 274ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const FloatColor& color = fill.filter.color; 275117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniform4f(mCaches->program().getUniform("colorBlend"), 276117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik color.r, color.g, color.b, color.a); 277b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik } else if (fill.filterMode == ProgramDescription::ColorFilterMode::Matrix) { 278117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniformMatrix4fv(mCaches->program().getUniform("colorMatrix"), 1, GL_FALSE, 279ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik fill.filter.matrix.matrix); 280117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniform4fv(mCaches->program().getUniform("colorMatrixVector"), 1, 281ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik fill.filter.matrix.vector); 282117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik } 2836c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 2840519c810a56bded1284fcb2ae40f438878c6585fChris Craik // Round rect clipping uniforms 2850519c810a56bded1284fcb2ae40f438878c6585fChris Craik if (glop.roundRectClipState) { 2860519c810a56bded1284fcb2ae40f438878c6585fChris Craik // TODO: avoid query, and cache values (or RRCS ptr) in program 2870519c810a56bded1284fcb2ae40f438878c6585fChris Craik const RoundRectClipState* state = glop.roundRectClipState; 2880519c810a56bded1284fcb2ae40f438878c6585fChris Craik const Rect& innerRect = state->innerRect; 2890519c810a56bded1284fcb2ae40f438878c6585fChris Craik glUniform4f(fill.program->getUniform("roundRectInnerRectLTRB"), 2900519c810a56bded1284fcb2ae40f438878c6585fChris Craik innerRect.left, innerRect.top, 2910519c810a56bded1284fcb2ae40f438878c6585fChris Craik innerRect.right, innerRect.bottom); 2920519c810a56bded1284fcb2ae40f438878c6585fChris Craik glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 2930519c810a56bded1284fcb2ae40f438878c6585fChris Craik 1, GL_FALSE, &state->matrix.data[0]); 2940519c810a56bded1284fcb2ae40f438878c6585fChris Craik 2950519c810a56bded1284fcb2ae40f438878c6585fChris Craik // add half pixel to round out integer rect space to cover pixel centers 2960519c810a56bded1284fcb2ae40f438878c6585fChris Craik float roundedOutRadius = state->radius + 0.5f; 2970519c810a56bded1284fcb2ae40f438878c6585fChris Craik glUniform1f(fill.program->getUniform("roundRectRadius"), 2980519c810a56bded1284fcb2ae40f438878c6585fChris Craik roundedOutRadius); 2990519c810a56bded1284fcb2ae40f438878c6585fChris Craik } 300ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik 301975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 3029372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 303117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // -------------------------------- 3046c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik // ---------- Mesh setup ---------- 305117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // -------------------------------- 306117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // vertices 3071b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindMeshBuffer(vertices.bufferObject); 3081b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindPositionVertexPointer(vertices.position, vertices.stride); 309117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 310117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // indices 3111b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindIndicesBuffer(indices.bufferObject); 312117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 313138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik // texture 314138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik if (fill.texture.texture != nullptr) { 31526bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik const Glop::Fill::TextureData& texture = fill.texture; 31626bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik // texture always takes slot 0, shader samplers increment from there 3170519c810a56bded1284fcb2ae40f438878c6585fChris Craik mCaches->textureState().activateTexture(0); 3180519c810a56bded1284fcb2ae40f438878c6585fChris Craik 3192a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv mCaches->textureState().bindTexture(texture.texture->target(), texture.texture->id()); 32026bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.clamp != GL_INVALID_ENUM) { 3212a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv texture.texture->setWrap(texture.clamp, false, false); 32230036092b40badecbe64d9c2bff4850132147f78Chris Craik } 32326bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.filter != GL_INVALID_ENUM) { 3242a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv texture.texture->setFilter(texture.filter, false, false); 32530036092b40badecbe64d9c2bff4850132147f78Chris Craik } 3260519c810a56bded1284fcb2ae40f438878c6585fChris Craik 32726bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.textureTransform) { 32826bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik glUniformMatrix4fv(fill.program->getUniform("mainTextureTransform"), 1, 32926bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik GL_FALSE, &texture.textureTransform->data[0]); 33026bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik } 331138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik } 332138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik 333138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik // vertex attributes (tex coord, color, alpha) 334138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { 335138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik meshState().enableTexCoordsVertexArray(); 336138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik meshState().bindTexCoordsVertexPointer(vertices.texCoord, vertices.stride); 3376c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } else { 3386c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik meshState().disableTexCoordsVertexArray(); 3396c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 340ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik int colorLocation = -1; 34153e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Color) { 342ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik colorLocation = fill.program->getAttrib("colors"); 343ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glEnableVertexAttribArray(colorLocation); 344ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride, vertices.color); 3456c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 346ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik int alphaLocation = -1; 34753e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Alpha) { 348ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik // NOTE: alpha vertex position is computed assuming no VBO 349ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const void* alphaCoords = ((const GLbyte*) vertices.position) + kVertexAlphaOffset; 350ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik alphaLocation = fill.program->getAttrib("vtxAlpha"); 351ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glEnableVertexAttribArray(alphaLocation); 352ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glVertexAttribPointer(alphaLocation, 1, GL_FLOAT, GL_FALSE, vertices.stride, alphaCoords); 3536c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 354922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Shader uniforms 355253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy SkiaShader::apply(*mCaches, fill.skiaShaderData, mViewportWidth, mViewportHeight); 356922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 357975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 358c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee Texture* texture = (fill.skiaShaderData.skiaShaderType & kBitmap_SkiaShaderType) ? 359c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee fill.skiaShaderData.bitmapData.bitmapTexture : nullptr; 360c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee const AutoTexture autoCleanup(texture); 3619372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 362117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 3636c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik // ---------- GL state setup ---------- 364117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 365031888744e24b5c7243ac99ec98b78aff5db1c78Chris Craik blend().setFactors(glop.blend.src, glop.blend.dst); 3666c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 367975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 3689372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 369117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 3702ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ---------- Actual drawing ---------- 371117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 372ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik if (indices.bufferObject == meshState().getQuadListIBO()) { 3732ab95d780b023152556d9f8659de734ec7b55047Chris Craik // Since the indexed quad list is of limited length, we loop over 3742ab95d780b023152556d9f8659de734ec7b55047Chris Craik // the glDrawXXX method while updating the vertex pointer 3750519c810a56bded1284fcb2ae40f438878c6585fChris Craik GLsizei elementsCount = mesh.elementCount; 376ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position); 3772ab95d780b023152556d9f8659de734ec7b55047Chris Craik while (elementsCount > 0) { 3789db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6); 3791b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindPositionVertexPointer(vertexData, vertices.stride); 38053e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { 3811b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindTexCoordsVertexPointer( 382ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik vertexData + kMeshTextureOffset, vertices.stride); 383f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik } 384f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik 3852ab95d780b023152556d9f8659de734ec7b55047Chris Craik glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr); 3862ab95d780b023152556d9f8659de734ec7b55047Chris Craik elementsCount -= drawCount; 387ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik vertexData += (drawCount / 6) * 4 * vertices.stride; 3882ab95d780b023152556d9f8659de734ec7b55047Chris Craik } 389ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik } else if (indices.bufferObject || indices.indices) { 390ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices); 3916c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } else { 3920519c810a56bded1284fcb2ae40f438878c6585fChris Craik glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount); 393117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik } 394117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 395975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 3969372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 3972ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ----------------------------------- 3982ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ---------- Mesh teardown ---------- 3992ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ----------------------------------- 40053e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Alpha) { 401ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glDisableVertexAttribArray(alphaLocation); 402ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik } 40353e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Color) { 404ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glDisableVertexAttribArray(colorLocation); 4056c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 4069372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 407975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 4086c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik} 4096c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 410117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craikvoid RenderState::dump() { 411117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik blend().dump(); 412117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik meshState().dump(); 413117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik scissor().dump(); 414117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik stencil().dump(); 415117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik} 416117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 4173b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace uirenderer */ 4183b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace android */ 419