BakedOpRenderer.cpp revision e29ce6f51d681af7649c0a7cddee97c471e43eb5
1b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik/* 2b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Copyright (C) 2015 The Android Open Source Project 3b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 4b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Licensed under the Apache License, Version 2.0 (the "License"); 5b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * you may not use this file except in compliance with the License. 6b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * You may obtain a copy of the License at 7b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 8b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * http://www.apache.org/licenses/LICENSE-2.0 9b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * 10b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * Unless required by applicable law or agreed to in writing, software 11b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * distributed under the License is distributed on an "AS IS" BASIS, 12b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * See the License for the specific language governing permissions and 14b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik * limitations under the License. 15b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik */ 16b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 17b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "BakedOpRenderer.h" 18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 19b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Caches.h" 20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Glop.h" 21b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "GlopBuilder.h" 229fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include "renderstate/OffscreenBufferPool.h" 23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "renderstate/RenderState.h" 24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "utils/GLUtils.h" 259fded232a9548a304e0145011df8849fba0dcda7Chris Craik#include "VertexBuffer.h" 26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 27a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik#include <algorithm> 28a1717271caac5e8ea3808c331d4141ac01a42134Chris Craik 29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android { 30b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer { 31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 32d3daa3198e2212c985c634821682d5819346b653Chris CraikOffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t height) { 339fded232a9548a304e0145011df8849fba0dcda7Chris Craik LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); 349fded232a9548a304e0145011df8849fba0dcda7Chris Craik 359fded232a9548a304e0145011df8849fba0dcda7Chris Craik OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height); 3698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik startRepaintLayer(buffer, Rect(width, height)); 370b7e8245db728d127ada698be63d78b33fc6e4daChris Craik return buffer; 380b7e8245db728d127ada698be63d78b33fc6e4daChris Craik} 390b7e8245db728d127ada698be63d78b33fc6e4daChris Craik 4098787e6c9b2c10b1ab7820bdac168686025b924aChris Craikvoid BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) { 41d3daa3198e2212c985c634821682d5819346b653Chris Craik LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); 42d3daa3198e2212c985c634821682d5819346b653Chris Craik 430b7e8245db728d127ada698be63d78b33fc6e4daChris Craik mRenderTarget.offscreenBuffer = offscreenBuffer; 44818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 455854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik // create and bind framebuffer 465854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.frameBufferId = mRenderState.genFramebuffer(); 475854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.bindFramebuffer(mRenderTarget.frameBufferId); 48818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 49818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // attach the texture to the FBO 50818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 510b7e8245db728d127ada698be63d78b33fc6e4daChris Craik offscreenBuffer->texture.id, 0); 52818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "startLayer FAILED"); 53818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE, 54818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik "framebuffer incomplete!"); 55818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 56818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // Change the viewport & ortho projection 570b7e8245db728d127ada698be63d78b33fc6e4daChris Craik setViewport(offscreenBuffer->viewportWidth, offscreenBuffer->viewportHeight); 5898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik 5998787e6c9b2c10b1ab7820bdac168686025b924aChris Craik clearColorBuffer(repaintRect); 60818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 61818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 625854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::endLayer() { 638d2cf943d9c7292e54726399faefdec4a01c084bChris Craik mRenderTarget.offscreenBuffer->updateMeshFromRegion(); 645854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.offscreenBuffer = nullptr; 65818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 66818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik // Detach the texture from the FBO 67818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); 68818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "endLayer FAILED"); 695854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.deleteFramebuffer(mRenderTarget.frameBufferId); 705854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.frameBufferId = -1; 71818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik} 72818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik 7398787e6c9b2c10b1ab7820bdac168686025b924aChris Craikvoid BakedOpRenderer::startFrame(uint32_t width, uint32_t height, const Rect& repaintRect) { 745854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.bindFramebuffer(0); 755854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik setViewport(width, height); 765854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mCaches.clearGarbage(); 77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 785854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik if (!mOpaque) { 7998787e6c9b2c10b1ab7820bdac168686025b924aChris Craik clearColorBuffer(repaintRect); 80b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 81b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 825854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik 835854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::endFrame() { 845854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mCaches.pathCache.trim(); 855854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mCaches.tessellationCache.trim(); 86b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 87b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if DEBUG_OPENGL 88b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik GLUtils::dumpGLErrors(); 89b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 90b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 91b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if DEBUG_MEMORY_USAGE 925854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mCaches.dumpMemoryUsage(); 93b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#else 94b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik if (Properties::debugLevel & kDebugMemory) { 955854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mCaches.dumpMemoryUsage(); 96b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik } 97b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif 98b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} 99b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik 1005854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::setViewport(uint32_t width, uint32_t height) { 1015854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.viewportWidth = width; 1025854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.viewportHeight = height; 1035854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderTarget.orthoMatrix.loadOrtho(width, height); 1045854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik 1055854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.setViewport(width, height); 1065854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.blend().syncEnabled(); 1075854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik} 1085854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik 10998787e6c9b2c10b1ab7820bdac168686025b924aChris Craikvoid BakedOpRenderer::clearColorBuffer(const Rect& rect) { 11098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik if (Rect(mRenderTarget.viewportWidth, mRenderTarget.viewportHeight).contains(rect)) { 11198787e6c9b2c10b1ab7820bdac168686025b924aChris Craik // Full viewport is being cleared - disable scissor 11298787e6c9b2c10b1ab7820bdac168686025b924aChris Craik mRenderState.scissor().setEnabled(false); 11398787e6c9b2c10b1ab7820bdac168686025b924aChris Craik } else { 11498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik // Requested rect is subset of viewport - scissor to it to avoid over-clearing 11598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik mRenderState.scissor().setEnabled(true); 11698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik mRenderState.scissor().set(rect.left, mRenderTarget.viewportHeight - rect.bottom, 11798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik rect.getWidth(), rect.getHeight()); 11898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik } 11998787e6c9b2c10b1ab7820bdac168686025b924aChris Craik glClear(GL_COLOR_BUFFER_BIT); 12098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik if (!mRenderTarget.frameBufferId) mHasDrawn = true; 12198787e6c9b2c10b1ab7820bdac168686025b924aChris Craik} 12298787e6c9b2c10b1ab7820bdac168686025b924aChris Craik 1235854b34881b1a747ac80b5077869ef270a92b1f4Chris CraikTexture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) { 12415c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap->pixelRef()); 1255854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik if (!texture) { 1265854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik return mCaches.textureCache.get(bitmap); 1275854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik } 1285854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik return texture; 1295854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik} 1305854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik 131e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craikvoid BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const Rect* clip) { 13215c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik mRenderState.scissor().setEnabled(clip != nullptr); 13315c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik if (clip) { 13415c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik mRenderState.scissor().set(clip->left, mRenderTarget.viewportHeight - clip->bottom, 13515c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik clip->getWidth(), clip->getHeight()); 1365854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik } 13715c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik if (dirtyBounds && mRenderTarget.offscreenBuffer) { 1388d2cf943d9c7292e54726399faefdec4a01c084bChris Craik // register layer damage to draw-back region 13915c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik android::Rect dirty(dirtyBounds->left, dirtyBounds->top, 14015c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik dirtyBounds->right, dirtyBounds->bottom); 1418d2cf943d9c7292e54726399faefdec4a01c084bChris Craik mRenderTarget.offscreenBuffer->region.orSelf(dirty); 1428d2cf943d9c7292e54726399faefdec4a01c084bChris Craik } 143e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik} 144e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 145e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craikvoid BakedOpRenderer::renderGlop(const Rect* dirtyBounds, const Rect* clip, const Glop& glop) { 146e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik prepareRender(dirtyBounds, clip); 1475854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik mRenderState.render(glop, mRenderTarget.orthoMatrix); 14898787e6c9b2c10b1ab7820bdac168686025b924aChris Craik if (!mRenderTarget.frameBufferId) mHasDrawn = true; 1495854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik} 1505854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik 151e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craikvoid BakedOpRenderer::renderFunctor(const FunctorOp& op, const BakedOpState& state) { 152e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik prepareRender(&state.computedState.clippedBounds, &state.computedState.clipRect); 153e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 154e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik DrawGlInfo info; 155e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik auto&& clip = state.computedState.clipRect; 156e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.clipLeft = clip.left; 157e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.clipTop = clip.top; 158e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.clipRight = clip.right; 159e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.clipBottom = clip.bottom; 160e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.isLayer = offscreenRenderTarget(); 161e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.width = mRenderTarget.viewportWidth; 162e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik info.height = mRenderTarget.viewportHeight; 163e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik state.computedState.transform.copyTo(&info.transform[0]); 164e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 165e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik mRenderState.invokeFunctor(op.functor, DrawGlInfo::kModeDraw, &info); 166e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik} 167e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik 16815c3f19a445b8df575911a16e8a6dba755a084b5Chris Craikvoid BakedOpRenderer::dirtyRenderTarget(const Rect& uiDirty) { 16915c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik if (mRenderTarget.offscreenBuffer) { 17015c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik android::Rect dirty(uiDirty.left, uiDirty.top, uiDirty.right, uiDirty.bottom); 17115c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik mRenderTarget.offscreenBuffer->region.orSelf(dirty); 17215c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik } 17315c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik} 17415c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik 175b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} // namespace uirenderer 176b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} // namespace android 177