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" 25caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy 269db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik#include <algorithm> 279db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik 28caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy#include <ui/ColorSpace.h> 29caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy 303b20251a355c88193c439f928a84ae69483fb488John Recknamespace android { 313b20251a355c88193c439f928a84ae69483fb488John Recknamespace uirenderer { 323b20251a355c88193c439f928a84ae69483fb488John Reck 330e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John ReckRenderState::RenderState(renderthread::RenderThread& thread) 340e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck : mRenderThread(thread) 353b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportWidth(0) 363b20251a355c88193c439f928a84ae69483fb488John Reck , mViewportHeight(0) 373b20251a355c88193c439f928a84ae69483fb488John Reck , mFramebuffer(0) { 380e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck mThreadId = pthread_self(); 393b20251a355c88193c439f928a84ae69483fb488John Reck} 403b20251a355c88193c439f928a84ae69483fb488John Reck 413b20251a355c88193c439f928a84ae69483fb488John ReckRenderState::~RenderState() { 4244eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 4396a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 443b20251a355c88193c439f928a84ae69483fb488John Reck} 453b20251a355c88193c439f928a84ae69483fb488John Reck 463b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::onGLContextCreated() { 4744eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 4896a5c4c7bab6718524de7253da8309143ab48befChris Craik "State object lifecycle not managed correctly"); 4945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextCreated(); 5038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck 5144eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mBlend = new Blend(); 5296a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = new MeshState(); 5396a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = new Scissor(); 5496a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = new Stencil(); 5596a5c4c7bab6718524de7253da8309143ab48befChris Craik 56642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck // Deferred because creation needs GL context for texture limits 57642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck if (!mLayerPool) { 58642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck mLayerPool = new OffscreenBufferPool(); 59642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck } 60642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck 613b20251a355c88193c439f928a84ae69483fb488John Reck // This is delayed because the first access of Caches makes GL calls 62ff5c8e8097e3eff910632a568195b798798cccccChris Craik if (!mCaches) { 63ff5c8e8097e3eff910632a568195b798798cccccChris Craik mCaches = &Caches::createInstance(*this); 64ff5c8e8097e3eff910632a568195b798798cccccChris Craik } 653b20251a355c88193c439f928a84ae69483fb488John Reck mCaches->init(); 663b20251a355c88193c439f928a84ae69483fb488John Reck} 673b20251a355c88193c439f928a84ae69483fb488John Reck 6857998017ff137f7d4ec33df21b6596141f8c4547John Reckstatic void layerLostGlContext(Layer* layer) { 698cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::OpenGL, 708cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel "layerLostGlContext on non GL layer"); 718cd3edfa15cc9cdbffa935d19ab894426b08d174Greg Daniel static_cast<GlLayer*>(layer)->onGlContextLost(); 7257998017ff137f7d4ec33df21b6596141f8c4547John Reck} 7357998017ff137f7d4ec33df21b6596141f8c4547John Reck 741d4774233304c484673e2af2c1de2ab41021c979Chris Craikvoid RenderState::onGLContextDestroyed() { 75642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck mLayerPool->clear(); 769fded232a9548a304e0145011df8849fba0dcda7Chris Craik 7796a5c4c7bab6718524de7253da8309143ab48befChris Craik // TODO: reset all cached state in state objects 7857998017ff137f7d4ec33df21b6596141f8c4547John Reck std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerLostGlContext); 7996a5c4c7bab6718524de7253da8309143ab48befChris Craik 8044eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->terminate(); 8144eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik 8244eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik delete mBlend; 8344eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mBlend = nullptr; 8496a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mMeshState; 8596a5c4c7bab6718524de7253da8309143ab48befChris Craik mMeshState = nullptr; 8696a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mScissor; 8796a5c4c7bab6718524de7253da8309143ab48befChris Craik mScissor = nullptr; 8896a5c4c7bab6718524de7253da8309143ab48befChris Craik delete mStencil; 8996a5c4c7bab6718524de7253da8309143ab48befChris Craik mStencil = nullptr; 9038e0c32852e3b9d8ca4a9d3791577f52536419cbJohn Reck 91c3f131696111a066d9efd9c7c3e37566a2a9fb89sergeyv destroyLayersInUpdater(); 9245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextDestroyed(); 9345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 9445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 9545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid RenderState::onVkContextCreated() { 9645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(mBlend || mMeshState || mScissor || mStencil, 9745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "State object lifecycle not managed correctly"); 9845ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextCreated(); 9945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 10045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 10145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielstatic void layerDestroyedVkContext(Layer* layer) { 10245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel LOG_ALWAYS_FATAL_IF(layer->getApi() != Layer::Api::Vulkan, 10345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel "layerLostVkContext on non Vulkan layer"); 10445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel static_cast<VkLayer*>(layer)->onVkContextDestroyed(); 10545ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 10645ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 10745ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Danielvoid RenderState::onVkContextDestroyed() { 108642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck mLayerPool->clear(); 10945ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel std::for_each(mActiveLayers.begin(), mActiveLayers.end(), layerDestroyedVkContext); 11045ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel GpuMemoryTracker::onGpuContextDestroyed(); 11145ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel} 11245ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel 11345ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg DanielGrContext* RenderState::getGrContext() const { 11445ec62ba72c5017fae7d8baab20bfb0d4c99c627Greg Daniel return mRenderThread.getGrContext(); 1151d4774233304c484673e2af2c1de2ab41021c979Chris Craik} 1161d4774233304c484673e2af2c1de2ab41021c979Chris Craik 1179fded232a9548a304e0145011df8849fba0dcda7Chris Craikvoid RenderState::flush(Caches::FlushMode mode) { 1189fded232a9548a304e0145011df8849fba0dcda7Chris Craik switch (mode) { 1199fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Full: 1209fded232a9548a304e0145011df8849fba0dcda7Chris Craik // fall through 1219fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Moderate: 1229fded232a9548a304e0145011df8849fba0dcda7Chris Craik // fall through 1239fded232a9548a304e0145011df8849fba0dcda7Chris Craik case Caches::FlushMode::Layers: 124642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck if (mLayerPool) mLayerPool->clear(); 1259fded232a9548a304e0145011df8849fba0dcda7Chris Craik break; 1269fded232a9548a304e0145011df8849fba0dcda7Chris Craik } 127642ebea6e14b72c512ef1168dc6edb061035ddedJohn Reck if (mCaches) mCaches->flush(mode); 1289fded232a9548a304e0145011df8849fba0dcda7Chris Craik} 1299fded232a9548a304e0145011df8849fba0dcda7Chris Craik 1309a814875c4e3a98fea99dae623f22268a9afa38aJohn Reckvoid RenderState::onBitmapDestroyed(uint32_t pixelRefId) { 13136393c3e8da725927357d7a235c18e2f6c1aea98John Reck if (mCaches && mCaches->textureCache.destroyTexture(pixelRefId)) { 1329a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck glFlush(); 1339a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck GL_CHECKPOINT(MODERATE); 1349a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck } 1359a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck} 1369a814875c4e3a98fea99dae623f22268a9afa38aJohn Reck 1373b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::setViewport(GLsizei width, GLsizei height) { 1383b20251a355c88193c439f928a84ae69483fb488John Reck mViewportWidth = width; 1393b20251a355c88193c439f928a84ae69483fb488John Reck mViewportHeight = height; 1403b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 1413b20251a355c88193c439f928a84ae69483fb488John Reck} 1423b20251a355c88193c439f928a84ae69483fb488John Reck 1433b20251a355c88193c439f928a84ae69483fb488John Reck 1443b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::getViewport(GLsizei* outWidth, GLsizei* outHeight) { 1453b20251a355c88193c439f928a84ae69483fb488John Reck *outWidth = mViewportWidth; 1463b20251a355c88193c439f928a84ae69483fb488John Reck *outHeight = mViewportHeight; 1473b20251a355c88193c439f928a84ae69483fb488John Reck} 1483b20251a355c88193c439f928a84ae69483fb488John Reck 1493b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::bindFramebuffer(GLuint fbo) { 1503b20251a355c88193c439f928a84ae69483fb488John Reck if (mFramebuffer != fbo) { 1513b20251a355c88193c439f928a84ae69483fb488John Reck mFramebuffer = fbo; 1523b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 1533b20251a355c88193c439f928a84ae69483fb488John Reck } 1543b20251a355c88193c439f928a84ae69483fb488John Reck} 1553b20251a355c88193c439f928a84ae69483fb488John Reck 1560b8d0677be2289bbc9e0b48c0878fb67d1cc0ebdJohn ReckGLuint RenderState::createFramebuffer() { 157818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik GLuint ret; 158818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glGenFramebuffers(1, &ret); 159818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik return ret; 160818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 161818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 162818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craikvoid RenderState::deleteFramebuffer(GLuint fbo) { 163818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik if (mFramebuffer == fbo) { 164818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // GL defines that deleting the currently bound FBO rebinds FBO 0. 165818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // Reflect this in our cached value. 166818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik mFramebuffer = 0; 167818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik } 168818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glDeleteFramebuffers(1, &fbo); 169818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 170818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 1713b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::invokeFunctor(Functor* functor, DrawGlInfo::Mode mode, DrawGlInfo* info) { 17295cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck if (mode == DrawGlInfo::kModeProcessNoContext) { 17395cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck // If there's no context we don't need to interrupt as there's 17495cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck // no gl state to save/restore 17595cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck (*functor)(mode, info); 17695cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck } else { 17795cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck interruptForFunctorInvoke(); 17895cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck (*functor)(mode, info); 17995cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck resumeFromFunctorInvoke(); 18095cd24bb9d000eb541bc7ec7e6b53d1c7e313076John Reck } 1813b20251a355c88193c439f928a84ae69483fb488John Reck} 1823b20251a355c88193c439f928a84ae69483fb488John Reck 1833b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::interruptForFunctorInvoke() { 1846c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik mCaches->setProgram(nullptr); 18544eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().resetActiveTexture(); 18696a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindMeshBuffer(); 18796a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().unbindIndicesBuffer(); 18896a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().resetVertexPointers(); 18996a5c4c7bab6718524de7253da8309143ab48befChris Craik meshState().disableTexCoordsVertexArray(); 1903b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 191253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy // TODO: We need a way to know whether the functor is sRGB aware (b/32072673) 192efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (mCaches->extensions().hasLinearBlending() && 193efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy mCaches->extensions().hasSRGBWriteControl()) { 194253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy glDisable(GL_FRAMEBUFFER_SRGB_EXT); 195253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy } 1963b20251a355c88193c439f928a84ae69483fb488John Reck} 1973b20251a355c88193c439f928a84ae69483fb488John Reck 1983b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::resumeFromFunctorInvoke() { 199efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy if (mCaches->extensions().hasLinearBlending() && 200efb4b06493fe7b1604c762a448b13c7af2845a8dRomain Guy mCaches->extensions().hasSRGBWriteControl()) { 201253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy glEnable(GL_FRAMEBUFFER_SRGB_EXT); 202253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy } 203253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy 2043b20251a355c88193c439f928a84ae69483fb488John Reck glViewport(0, 0, mViewportWidth, mViewportHeight); 2053b20251a355c88193c439f928a84ae69483fb488John Reck glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); 2063b20251a355c88193c439f928a84ae69483fb488John Reck debugOverdraw(false, false); 2073b20251a355c88193c439f928a84ae69483fb488John Reck 2083b20251a355c88193c439f928a84ae69483fb488John Reck glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 2093b20251a355c88193c439f928a84ae69483fb488John Reck 21065fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().invalidate(); 21144eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik blend().invalidate(); 2123b20251a355c88193c439f928a84ae69483fb488John Reck 21344eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().activateTexture(0); 21444eb2c00861098dd3e2950d923646814b4cc57c2Chris Craik mCaches->textureState().resetBoundTextures(); 2153b20251a355c88193c439f928a84ae69483fb488John Reck} 2163b20251a355c88193c439f928a84ae69483fb488John Reck 2173b20251a355c88193c439f928a84ae69483fb488John Reckvoid RenderState::debugOverdraw(bool enable, bool clear) { 2182507c34d91bb0d722b6012e85cb47387b2aa6873Chris Craik if (Properties::debugOverdraw && mFramebuffer == 0) { 2193b20251a355c88193c439f928a84ae69483fb488John Reck if (clear) { 22065fe5eeb19e2e15c8b1ee91e8a2dcf0c25e48ca6Chris Craik scissor().setEnabled(false); 22196a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().clear(); 2223b20251a355c88193c439f928a84ae69483fb488John Reck } 2233b20251a355c88193c439f928a84ae69483fb488John Reck if (enable) { 22496a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().enableDebugWrite(); 2253b20251a355c88193c439f928a84ae69483fb488John Reck } else { 22696a5c4c7bab6718524de7253da8309143ab48befChris Craik stencil().disable(); 2273b20251a355c88193c439f928a84ae69483fb488John Reck } 2283b20251a355c88193c439f928a84ae69483fb488John Reck } 2293b20251a355c88193c439f928a84ae69483fb488John Reck} 2303b20251a355c88193c439f928a84ae69483fb488John Reck 2313e9999bd866fac71c72e6b484a9836c87c328a08sergeyvstatic void destroyLayerInUpdater(DeferredLayerUpdater* layerUpdater) { 2323e9999bd866fac71c72e6b484a9836c87c328a08sergeyv layerUpdater->destroyLayer(); 2333e9999bd866fac71c72e6b484a9836c87c328a08sergeyv} 2343e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 2353e9999bd866fac71c72e6b484a9836c87c328a08sergeyvvoid RenderState::destroyLayersInUpdater() { 2363e9999bd866fac71c72e6b484a9836c87c328a08sergeyv std::for_each(mActiveLayerUpdaters.begin(), mActiveLayerUpdaters.end(), destroyLayerInUpdater); 2373e9999bd866fac71c72e6b484a9836c87c328a08sergeyv} 2383e9999bd866fac71c72e6b484a9836c87c328a08sergeyv 2390e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckclass DecStrongTask : public renderthread::RenderTask { 2400e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckpublic: 241c6baf563ba6aa207a48317c177b29f1d2b70cf3dChih-Hung Hsieh explicit DecStrongTask(VirtualLightRefBase* object) : mObject(object) {} 2420e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 243d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik virtual void run() override { 244d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject->decStrong(nullptr); 245d41c4d8c732095ae99c955b6b82f7306633004b1Chris Craik mObject = nullptr; 2460e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck delete this; 2470e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck } 2480e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2490e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckprivate: 2500e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck VirtualLightRefBase* mObject; 2510e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck}; 2520e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2530e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reckvoid RenderState::postDecStrong(VirtualLightRefBase* object) { 254a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck if (pthread_equal(mThreadId, pthread_self())) { 255a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck object->decStrong(nullptr); 256a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck } else { 257a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck mRenderThread.queue(new DecStrongTask(object)); 258a55b5d6c65cde2b7cc28bb3ea160bfaaef7a446aJohn Reck } 2590e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck} 2600e89e2b7bcb2c035e8cee77f93120e7c5617f8d2John Reck 2616c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik/////////////////////////////////////////////////////////////////////////////// 2626c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik// Render 2636c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik/////////////////////////////////////////////////////////////////////////////// 2646c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 265530a2b44d9a4b40d028c912ade858da73081ed85Arunvoid RenderState::render(const Glop& glop, const Matrix4& orthoMatrix, 266530a2b44d9a4b40d028c912ade858da73081ed85Arun bool overrideDisableBlending) { 2676c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik const Glop::Mesh& mesh = glop.mesh; 268ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const Glop::Mesh::Vertices& vertices = mesh.vertices; 269ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const Glop::Mesh::Indices& indices = mesh.indices; 2700519c810a56bded1284fcb2ae40f438878c6585fChris Craik const Glop::Fill& fill = glop.fill; 2716c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 272975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 2739372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 2740519c810a56bded1284fcb2ae40f438878c6585fChris Craik // --------------------------------------------- 2750519c810a56bded1284fcb2ae40f438878c6585fChris Craik // ---------- Program + uniform setup ---------- 2760519c810a56bded1284fcb2ae40f438878c6585fChris Craik // --------------------------------------------- 2770519c810a56bded1284fcb2ae40f438878c6585fChris Craik mCaches->setProgram(fill.program); 2786c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 2790519c810a56bded1284fcb2ae40f438878c6585fChris Craik if (fill.colorEnabled) { 2800519c810a56bded1284fcb2ae40f438878c6585fChris Craik fill.program->setColor(fill.color); 2810519c810a56bded1284fcb2ae40f438878c6585fChris Craik } 2826c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 28312efe649d3f5df8e81f4b78179939c1d488673a0Chris Craik fill.program->set(orthoMatrix, 2846c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik glop.transform.modelView, 28553e51e4aa933f9603587e1780f446c18816bf9beChris Craik glop.transform.meshTransform(), 28653e51e4aa933f9603587e1780f446c18816bf9beChris Craik glop.transform.transformFlags & TransformFlags::OffsetByFudgeFactor); 287117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 2880519c810a56bded1284fcb2ae40f438878c6585fChris Craik // Color filter uniforms 289b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik if (fill.filterMode == ProgramDescription::ColorFilterMode::Blend) { 290ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const FloatColor& color = fill.filter.color; 291117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniform4f(mCaches->program().getUniform("colorBlend"), 292117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik color.r, color.g, color.b, color.a); 293b9ce116dac378b4cf4490f265dcbd5704a1dd43cChris Craik } else if (fill.filterMode == ProgramDescription::ColorFilterMode::Matrix) { 294117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniformMatrix4fv(mCaches->program().getUniform("colorMatrix"), 1, GL_FALSE, 295ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik fill.filter.matrix.matrix); 296117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik glUniform4fv(mCaches->program().getUniform("colorMatrixVector"), 1, 297ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik fill.filter.matrix.vector); 298117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik } 2996c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 3000519c810a56bded1284fcb2ae40f438878c6585fChris Craik // Round rect clipping uniforms 3010519c810a56bded1284fcb2ae40f438878c6585fChris Craik if (glop.roundRectClipState) { 3020519c810a56bded1284fcb2ae40f438878c6585fChris Craik // TODO: avoid query, and cache values (or RRCS ptr) in program 3030519c810a56bded1284fcb2ae40f438878c6585fChris Craik const RoundRectClipState* state = glop.roundRectClipState; 3040519c810a56bded1284fcb2ae40f438878c6585fChris Craik const Rect& innerRect = state->innerRect; 3050519c810a56bded1284fcb2ae40f438878c6585fChris Craik 3060519c810a56bded1284fcb2ae40f438878c6585fChris Craik // add half pixel to round out integer rect space to cover pixel centers 3070519c810a56bded1284fcb2ae40f438878c6585fChris Craik float roundedOutRadius = state->radius + 0.5f; 30806e9f324ef5b723622647a6f111c38cb2d479869Arun 30906e9f324ef5b723622647a6f111c38cb2d479869Arun // Divide by the radius to simplify the calculations in the fragment shader 31006e9f324ef5b723622647a6f111c38cb2d479869Arun // roundRectPos is also passed from vertex shader relative to top/left & radius 31106e9f324ef5b723622647a6f111c38cb2d479869Arun glUniform4f(fill.program->getUniform("roundRectInnerRectLTWH"), 31206e9f324ef5b723622647a6f111c38cb2d479869Arun innerRect.left / roundedOutRadius, innerRect.top / roundedOutRadius, 31306e9f324ef5b723622647a6f111c38cb2d479869Arun (innerRect.right - innerRect.left) / roundedOutRadius, 31406e9f324ef5b723622647a6f111c38cb2d479869Arun (innerRect.bottom - innerRect.top) / roundedOutRadius); 31506e9f324ef5b723622647a6f111c38cb2d479869Arun 31606e9f324ef5b723622647a6f111c38cb2d479869Arun glUniformMatrix4fv(fill.program->getUniform("roundRectInvTransform"), 31706e9f324ef5b723622647a6f111c38cb2d479869Arun 1, GL_FALSE, &state->matrix.data[0]); 31806e9f324ef5b723622647a6f111c38cb2d479869Arun 3190519c810a56bded1284fcb2ae40f438878c6585fChris Craik glUniform1f(fill.program->getUniform("roundRectRadius"), 3200519c810a56bded1284fcb2ae40f438878c6585fChris Craik roundedOutRadius); 3210519c810a56bded1284fcb2ae40f438878c6585fChris Craik } 322ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik 323975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 3249372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 325117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // -------------------------------- 3266c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik // ---------- Mesh setup ---------- 327117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // -------------------------------- 328117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // vertices 3291b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindMeshBuffer(vertices.bufferObject); 3301b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindPositionVertexPointer(vertices.position, vertices.stride); 331117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 332117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // indices 3331b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindIndicesBuffer(indices.bufferObject); 334117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 335138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik // texture 336138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik if (fill.texture.texture != nullptr) { 33726bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik const Glop::Fill::TextureData& texture = fill.texture; 33826bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik // texture always takes slot 0, shader samplers increment from there 3390519c810a56bded1284fcb2ae40f438878c6585fChris Craik mCaches->textureState().activateTexture(0); 3400519c810a56bded1284fcb2ae40f438878c6585fChris Craik 3412a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv mCaches->textureState().bindTexture(texture.texture->target(), texture.texture->id()); 34226bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.clamp != GL_INVALID_ENUM) { 3432a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv texture.texture->setWrap(texture.clamp, false, false); 34430036092b40badecbe64d9c2bff4850132147f78Chris Craik } 34526bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.filter != GL_INVALID_ENUM) { 3462a38c42e921451abebb4ee5f5ecd738f1b6b04edsergeyv texture.texture->setFilter(texture.filter, false, false); 34730036092b40badecbe64d9c2bff4850132147f78Chris Craik } 3480519c810a56bded1284fcb2ae40f438878c6585fChris Craik 34926bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik if (texture.textureTransform) { 35026bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik glUniformMatrix4fv(fill.program->getUniform("mainTextureTransform"), 1, 35126bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik GL_FALSE, &texture.textureTransform->data[0]); 35226bf34200e40a0fa8c66366559aa016380cd8c6fChris Craik } 353138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik } 354138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik 355138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik // vertex attributes (tex coord, color, alpha) 356138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { 357138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik meshState().enableTexCoordsVertexArray(); 358138c21fbec12bead3c7ca1f181c3fd35542ccb00Chris Craik meshState().bindTexCoordsVertexPointer(vertices.texCoord, vertices.stride); 3596c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } else { 3606c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik meshState().disableTexCoordsVertexArray(); 3616c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 362ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik int colorLocation = -1; 36353e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Color) { 364ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik colorLocation = fill.program->getAttrib("colors"); 365ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glEnableVertexAttribArray(colorLocation); 366ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride, vertices.color); 3676c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 368ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik int alphaLocation = -1; 36953e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Alpha) { 370ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik // NOTE: alpha vertex position is computed assuming no VBO 371ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const void* alphaCoords = ((const GLbyte*) vertices.position) + kVertexAlphaOffset; 372ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik alphaLocation = fill.program->getAttrib("vtxAlpha"); 373ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glEnableVertexAttribArray(alphaLocation); 374ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glVertexAttribPointer(alphaLocation, 1, GL_FLOAT, GL_FALSE, vertices.stride, alphaCoords); 3756c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 376922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik // Shader uniforms 377253f2c213f6ecda63b6872aee77bd30d5ec07c82Romain Guy SkiaShader::apply(*mCaches, fill.skiaShaderData, mViewportWidth, mViewportHeight); 378922d3a7f6f8c1c05a996ee3e91e8cbadfff560c9Chris Craik 379975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 380c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee Texture* texture = (fill.skiaShaderData.skiaShaderType & kBitmap_SkiaShaderType) ? 381c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee fill.skiaShaderData.bitmapData.bitmapTexture : nullptr; 382c5a3efd28668a62df3e3b364b49624c5af7549b6Dohyun Lee const AutoTexture autoCleanup(texture); 3839372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 384caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy // If we have a shader and a base texture, the base texture is assumed to be an alpha mask 385caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy // which means the color space conversion applies to the shader's bitmap 386caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy Texture* colorSpaceTexture = texture != nullptr ? texture : fill.texture.texture; 387caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy if (colorSpaceTexture != nullptr) { 388caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy if (colorSpaceTexture->hasColorSpaceConversion()) { 389caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector(); 390caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy glUniformMatrix3fv(fill.program->getUniform("colorSpaceMatrix"), 1, 391caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy GL_FALSE, connector->getTransform().asArray()); 392caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy } 393caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy 394caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy TransferFunctionType transferFunction = colorSpaceTexture->getTransferFunctionType(); 395caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy if (transferFunction != TransferFunctionType::None) { 396caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy const ColorSpaceConnector* connector = colorSpaceTexture->getColorSpaceConnector(); 397caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy const ColorSpace& source = connector->getSource(); 398caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy 399caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy switch (transferFunction) { 400caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy case TransferFunctionType::None: 401caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy break; 402caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy case TransferFunctionType::Full: 403caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy glUniform1fv(fill.program->getUniform("transferFunction"), 7, 404caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy reinterpret_cast<const float*>(&source.getTransferParameters().g)); 405caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy break; 406caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy case TransferFunctionType::Limited: 407caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy glUniform1fv(fill.program->getUniform("transferFunction"), 5, 408caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy reinterpret_cast<const float*>(&source.getTransferParameters().g)); 409caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy break; 410caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy case TransferFunctionType::Gamma: 411caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy glUniform1f(fill.program->getUniform("transferFunctionGamma"), 412caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy source.getTransferParameters().g); 413caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy break; 414caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy } 415caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy } 416caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy } 417caaaa66e57293e4a6f312649bf472eab84d5c7feRomain Guy 418117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 4196c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik // ---------- GL state setup ---------- 420117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 421530a2b44d9a4b40d028c912ade858da73081ed85Arun if (CC_UNLIKELY(overrideDisableBlending)) { 422530a2b44d9a4b40d028c912ade858da73081ed85Arun blend().setFactors(GL_ZERO, GL_ZERO); 423530a2b44d9a4b40d028c912ade858da73081ed85Arun } else { 424530a2b44d9a4b40d028c912ade858da73081ed85Arun blend().setFactors(glop.blend.src, glop.blend.dst); 425530a2b44d9a4b40d028c912ade858da73081ed85Arun } 4266c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 427975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 4289372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 429117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 4302ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ---------- Actual drawing ---------- 431117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik // ------------------------------------ 432ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik if (indices.bufferObject == meshState().getQuadListIBO()) { 4332ab95d780b023152556d9f8659de734ec7b55047Chris Craik // Since the indexed quad list is of limited length, we loop over 4342ab95d780b023152556d9f8659de734ec7b55047Chris Craik // the glDrawXXX method while updating the vertex pointer 4350519c810a56bded1284fcb2ae40f438878c6585fChris Craik GLsizei elementsCount = mesh.elementCount; 436ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik const GLbyte* vertexData = static_cast<const GLbyte*>(vertices.position); 4372ab95d780b023152556d9f8659de734ec7b55047Chris Craik while (elementsCount > 0) { 4389db58c031f8ffa102a6d585cb585bed3bdb911a9Chris Craik GLsizei drawCount = std::min(elementsCount, (GLsizei) kMaxNumberOfQuads * 6); 439b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun GLsizei vertexCount = (drawCount / 6) * 4; 4401b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindPositionVertexPointer(vertexData, vertices.stride); 44153e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::TextureCoord) { 4421b7db4000eabb570697f4c5097588acbfa4df62bChris Craik meshState().bindTexCoordsVertexPointer( 443ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik vertexData + kMeshTextureOffset, vertices.stride); 444f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik } 445f27133df2d179c99d6bc1ae644af09e9153a0071Chris Craik 446b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun if (mCaches->extensions().getMajorGlVersion() >= 3) { 447b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun glDrawRangeElements(mesh.primitiveMode, 0, vertexCount-1, drawCount, GL_UNSIGNED_SHORT, nullptr); 448b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun } else { 449b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun glDrawElements(mesh.primitiveMode, drawCount, GL_UNSIGNED_SHORT, nullptr); 450b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun } 4512ab95d780b023152556d9f8659de734ec7b55047Chris Craik elementsCount -= drawCount; 452b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun vertexData += vertexCount * vertices.stride; 4532ab95d780b023152556d9f8659de734ec7b55047Chris Craik } 454ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik } else if (indices.bufferObject || indices.indices) { 455b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun if (mCaches->extensions().getMajorGlVersion() >= 3) { 456b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun // use glDrawRangeElements to reduce CPU overhead (otherwise the driver has to determine the min/max index values) 457b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun glDrawRangeElements(mesh.primitiveMode, 0, mesh.vertexCount-1, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices); 458b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun } else { 459b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun glDrawElements(mesh.primitiveMode, mesh.elementCount, GL_UNSIGNED_SHORT, indices.indices); 460b0a9477c8e07d4530f07c78a5d20b4cde0fe8d60Arun } 4616c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } else { 4620519c810a56bded1284fcb2ae40f438878c6585fChris Craik glDrawArrays(mesh.primitiveMode, 0, mesh.elementCount); 463117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik } 464117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 465975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 4669372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 4672ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ----------------------------------- 4682ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ---------- Mesh teardown ---------- 4692ab95d780b023152556d9f8659de734ec7b55047Chris Craik // ----------------------------------- 47053e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Alpha) { 471ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glDisableVertexAttribArray(alphaLocation); 472ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik } 47353e51e4aa933f9603587e1780f446c18816bf9beChris Craik if (vertices.attribFlags & VertexAttribFlags::Color) { 474ef2507439c08f4e9c4c9bba1c6243ca9df2ee827Chris Craik glDisableVertexAttribArray(colorLocation); 4756c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik } 4769372ac3621848085e77b867f220c0b5ffce4010dJohn Reck 477975591a7af883d866d86ab819e164c6004694744John Reck GL_CHECKPOINT(MODERATE); 4786c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik} 4796c15ffa196fc9b7724c189d833c3435d8db12266Chris Craik 480117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craikvoid RenderState::dump() { 481117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik blend().dump(); 482117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik meshState().dump(); 483117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik scissor().dump(); 484117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik stencil().dump(); 485117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik} 486117bdbcfa3e8306dad21e7e01fa71b00cdfa7265Chris Craik 4873b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace uirenderer */ 4883b20251a355c88193c439f928a84ae69483fb488John Reck} /* namespace android */ 489