BakedOpRenderer.cpp revision 5854b34881b1a747ac80b5077869ef270a92b1f4
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"
22b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "renderstate/RenderState.h"
23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "utils/GLUtils.h"
24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android {
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer {
27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
285854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
295854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik// OffscreenBuffer
305854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
315854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
325854b34881b1a747ac80b5077869ef270a92b1f4Chris CraikOffscreenBuffer::OffscreenBuffer(Caches& caches, uint32_t textureWidth, uint32_t textureHeight,
335854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        uint32_t viewportWidth, uint32_t viewportHeight)
345854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        : texture(caches)
355854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        , texCoords(0, viewportHeight / float(textureHeight), viewportWidth / float(textureWidth), 0) {
365854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    texture.width = textureWidth;
375854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    texture.height = textureHeight;
385854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
395854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    caches.textureState().activateTexture(0);
405854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    glGenTextures(1, &texture.id);
415854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    caches.textureState().bindTexture(GL_TEXTURE_2D, texture.id);
425854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
435854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    texture.setWrap(GL_CLAMP_TO_EDGE, false, false, GL_TEXTURE_2D);
445854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // not setting filter on texture, since it's set when drawing, based on transform
455854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
465854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
475854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture.width, texture.height, 0,
485854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
49b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
50b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
515854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
525854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik// BakedOpRenderer
535854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
54818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
555854b34881b1a747ac80b5077869ef270a92b1f4Chris CraikOffscreenBuffer* BakedOpRenderer::startLayer(uint32_t width, uint32_t height) {
565854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer...");
57818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
585854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // TODO: really should be caching these!
595854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    OffscreenBuffer* buffer = new OffscreenBuffer(mCaches, width, height, width, height);
605854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.offscreenBuffer = buffer;
61818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
625854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // create and bind framebuffer
635854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.frameBufferId = mRenderState.genFramebuffer();
645854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.bindFramebuffer(mRenderTarget.frameBufferId);
65818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
66818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    // attach the texture to the FBO
67818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
685854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            buffer->texture.id, 0);
69818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "startLayer FAILED");
70818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    LOG_ALWAYS_FATAL_IF(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE,
71818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik            "framebuffer incomplete!");
72818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
73818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    // Clear the FBO
745854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.scissor().setEnabled(false);
75818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    glClear(GL_COLOR_BUFFER_BIT);
76818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
77818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    // Change the viewport & ortho projection
785854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    setViewport(width, height);
795854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    return buffer;
80818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik}
81818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
825854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::endLayer() {
835854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.offscreenBuffer = nullptr;
84818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
85818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    // Detach the texture from the FBO
86818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
87818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    LOG_ALWAYS_FATAL_IF(GLUtils::dumpGLErrors(), "endLayer FAILED");
885854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.deleteFramebuffer(mRenderTarget.frameBufferId);
895854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.frameBufferId = -1;
90818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik}
91818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
925854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::startFrame(uint32_t width, uint32_t height) {
935854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.bindFramebuffer(0);
945854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    setViewport(width, height);
955854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mCaches.clearGarbage();
96b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
975854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    if (!mOpaque) {
98b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        // TODO: partial invalidate!
995854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        mRenderState.scissor().setEnabled(false);
100b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        glClear(GL_COLOR_BUFFER_BIT);
1015854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        mHasDrawn = true;
102b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    }
103b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
1045854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1055854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::endFrame() {
1065854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mCaches.pathCache.trim();
1075854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mCaches.tessellationCache.trim();
108b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
109b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if DEBUG_OPENGL
110b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    GLUtils::dumpGLErrors();
111b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif
112b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
113b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#if DEBUG_MEMORY_USAGE
1145854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mCaches.dumpMemoryUsage();
115b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#else
116b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    if (Properties::debugLevel & kDebugMemory) {
1175854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        mCaches.dumpMemoryUsage();
118b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    }
119b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#endif
120b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
121b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1225854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::setViewport(uint32_t width, uint32_t height) {
1235854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.viewportWidth = width;
1245854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.viewportHeight = height;
1255854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderTarget.orthoMatrix.loadOrtho(width, height);
1265854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1275854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.setViewport(width, height);
1285854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.blend().syncEnabled();
1295854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik}
1305854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1315854b34881b1a747ac80b5077869ef270a92b1f4Chris CraikTexture* BakedOpRenderer::getTexture(const SkBitmap* bitmap) {
1325854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    Texture* texture = mRenderState.assetAtlas().getEntryTexture(bitmap);
1335854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    if (!texture) {
1345854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        return mCaches.textureCache.get(bitmap);
1355854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    }
1365854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    return texture;
1375854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik}
1385854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1395854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpRenderer::renderGlop(const BakedOpState& state, const Glop& glop) {
1405854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    bool useScissor = state.computedState.clipSideFlags != OpClipSideFlags::None;
1415854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.scissor().setEnabled(useScissor);
1425854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    if (useScissor) {
1435854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        const Rect& clip = state.computedState.clipRect;
1445854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        mRenderState.scissor().set(clip.left, mRenderTarget.viewportHeight - clip.bottom,
1455854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            clip.getWidth(), clip.getHeight());
1465854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    }
1475854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mRenderState.render(glop, mRenderTarget.orthoMatrix);
1485854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    mHasDrawn = true;
1495854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik}
1505854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1515854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
1525854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik// static BakedOpDispatcher methods
1535854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik////////////////////////////////////////////////////////////////////////////////
1545854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1555854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onRenderNodeOp(BakedOpRenderer&, const RenderNodeOp&, const BakedOpState&) {
156b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    LOG_ALWAYS_FATAL("unsupported operation");
157b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
158b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1595854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onBitmapOp(BakedOpRenderer& renderer, const BitmapOp& op, const BakedOpState& state) {
1605854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    renderer.caches().textureState().activateTexture(0); // TODO: should this be automatic, and/or elsewhere?
1615854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    Texture* texture = renderer.getTexture(op.bitmap);
162b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    if (!texture) return;
163b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    const AutoTexture autoCleanup(texture);
164b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
165b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    const int textureFillFlags = (op.bitmap->colorType() == kAlpha_8_SkColorType)
166b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            ? TextureFillFlags::IsAlphaMaskTexture : TextureFillFlags::None;
167b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Glop glop;
1685854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
169b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setRoundRectClipState(state.roundRectClipState)
170b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setMeshTexturedUnitQuad(texture->uvMapper)
171b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setFillTexturePaint(*texture, textureFillFlags, op.paint, state.alpha)
172b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setTransform(state.computedState.transform, TransformFlags::None)
173b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setModelViewMapUnitToRectSnap(Rect(0, 0, texture->width, texture->height))
174b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .build();
1755854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    renderer.renderGlop(state, glop);
176b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
177b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1785854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onRectOp(BakedOpRenderer& renderer, const RectOp& op, const BakedOpState& state) {
179b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Glop glop;
1805854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
181b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setRoundRectClipState(state.roundRectClipState)
182b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setMeshUnitQuad()
183b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setFillPaint(*op.paint, state.alpha)
184b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setTransform(state.computedState.transform, TransformFlags::None)
185b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setModelViewMapUnitToRect(op.unmappedBounds)
186b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .build();
1875854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    renderer.renderGlop(state, glop);
188b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
189b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1905854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onSimpleRectsOp(BakedOpRenderer& renderer, const SimpleRectsOp& op, const BakedOpState& state) {
191b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik    Glop glop;
1925854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
193b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setRoundRectClipState(state.roundRectClipState)
194b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setMeshIndexedQuads(&op.vertices[0], op.vertexCount / 4)
195b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setFillPaint(*op.paint, state.alpha)
196b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setTransform(state.computedState.transform, TransformFlags::None)
197b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .setModelViewOffsetRect(0, 0, op.unmappedBounds)
198b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik            .build();
1995854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    renderer.renderGlop(state, glop);
200b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik}
201b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
2025854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onBeginLayerOp(BakedOpRenderer& renderer, const BeginLayerOp& op, const BakedOpState& state) {
2036fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik    LOG_ALWAYS_FATAL("unsupported operation");
2046fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik}
2056fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik
2065854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onEndLayerOp(BakedOpRenderer& renderer, const EndLayerOp& op, const BakedOpState& state) {
2076fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik    LOG_ALWAYS_FATAL("unsupported operation");
2086fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik}
2096fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik
2105854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikvoid BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, const BakedOpState& state) {
2115854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    OffscreenBuffer* buffer = *op.layerHandle;
212818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
2135854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // TODO: extend this to handle HW layers & paint properties which
2145854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // reside in node.properties().layerProperties()
2155854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    float layerAlpha = (op.paint->getAlpha() / 255.0f) * state.alpha;
216818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    const bool tryToSnap = state.computedState.transform.isPureTranslate();
217818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik    Glop glop;
2185854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
219818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik            .setRoundRectClipState(state.roundRectClipState)
2205854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            .setMeshTexturedUvQuad(nullptr, buffer->texCoords)
2215854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            .setFillLayer(buffer->texture, op.paint->getColorFilter(), layerAlpha, PaintUtils::getXfermodeDirect(op.paint), Blend::ModeOrderSwap::NoSwap)
222818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik            .setTransform(state.computedState.transform, TransformFlags::None)
223818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik            .setModelViewMapUnitToRectOptionalSnap(tryToSnap, op.unmappedBounds)
224818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik            .build();
2255854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    renderer.renderGlop(state, glop);
2265854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
2275854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // destroy and delete, since each clipped saveLayer is only drawn once.
2285854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    buffer->texture.deleteTexture();
2295854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
2305854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // TODO: return texture/offscreenbuffer to cache!
2315854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    delete buffer;
2326fe991e5e76f9af9dab960100d5768d96d5f4daaChris Craik}
233b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
234b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} // namespace uirenderer
235b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik} // namespace android
236