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
17419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik#pragma once
18b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
19b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "BakedOpState.h"
20b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik#include "Matrix.h"
217435eb148e72382126e9073183e881357bb38a8bChris Craik#include "utils/Macros.h"
22b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
23b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace android {
24b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craiknamespace uirenderer {
25b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
26b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass Caches;
27b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikstruct Glop;
28818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craikclass Layer;
29b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass RenderState;
30e4db79de127cfe961195f52907af8451026eaa20Chris Craikstruct ClipBase;
31b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
325854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik/**
335854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik * Main rendering manager for a collection of work - one frame + any contained FBOs.
345854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik *
355854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik * Manages frame and FBO lifecycle, binding the GL framebuffer as appropriate. This is the only
365854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik * place where FBOs are bound, created, and destroyed.
375854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik *
385854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik * All rendering operations will be sent by the Dispatcher, a collection of static methods,
395854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik * which has intentionally limited access to the renderer functionality.
405854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik */
41b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikclass BakedOpRenderer {
42b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craikpublic:
43419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&);
4498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    /**
4598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik     * Position agnostic shadow lighting info. Used with all shadow ops in scene.
4698787e6c9b2c10b1ab7820bdac168686025b924aChris Craik     */
4798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    struct LightInfo {
486e068c0182f6f85bccb855a647510724d1c65a13Chris Craik        LightInfo() : LightInfo(0, 0) {}
491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck        LightInfo(uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha)
501bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                : ambientShadowAlpha(ambientShadowAlpha), spotShadowAlpha(spotShadowAlpha) {}
517db5ffb7dbd30202468459e2ef4426e91d4fcbb3John Reck        uint8_t ambientShadowAlpha;
527db5ffb7dbd30202468459e2ef4426e91d4fcbb3John Reck        uint8_t spotShadowAlpha;
5398787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    };
5498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
5507ae505d4045e2b1ae501e87560984dae06f9dd8Romain Guy    BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, bool wideColorGamut,
561bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                    const LightInfo& lightInfo)
57419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik            : mGlopReceiver(DefaultGlopReceiver)
58419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik            , mRenderState(renderState)
595854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik            , mCaches(caches)
6098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik            , mOpaque(opaque)
6107ae505d4045e2b1ae501e87560984dae06f9dd8Romain Guy            , mWideColorGamut(wideColorGamut)
621bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck            , mLightInfo(lightInfo) {}
63b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
645854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    RenderState& renderState() { return mRenderState; }
655854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    Caches& caches() { return mCaches; }
66818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik
6798787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect);
68e4db79de127cfe961195f52907af8451026eaa20Chris Craik    void endFrame(const Rect& repaintRect);
697435eb148e72382126e9073183e881357bb38a8bChris Craik    WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height);
7074af6e282f8a8f75928a071e8200039517cf5c12Chris Craik    void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer);
7198787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect);
725854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    void endLayer();
737435eb148e72382126e9073183e881357bb38a8bChris Craik    WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area);
74b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
75ec4a4b13eae2241d1613890c1c1c096bed891845sergeyv    Texture* getTexture(Bitmap* bitmap);
76e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik    const LightInfo& getLightInfo() const { return mLightInfo; }
77b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
7815c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    void renderGlop(const BakedOpState& state, const Glop& glop) {
791bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck        renderGlop(&state.computedState.clippedBounds, state.computedState.getClipIfNeeded(), glop);
8015c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    }
81e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik    void renderFunctor(const FunctorOp& op, const BakedOpState& state);
8215c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik
83419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) {
84419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik        mGlopReceiver(*this, dirtyBounds, clip, glop);
85419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    }
8615c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; }
8715c3f19a445b8df575911a16e8a6dba755a084b5Chris Craik    void dirtyRenderTarget(const Rect& dirtyRect);
88e29ce6f51d681af7649c0a7cddee97c471e43eb5Chris Craik    bool didDraw() const { return mHasDrawn; }
891dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik
901dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    uint32_t getViewportWidth() const { return mRenderTarget.viewportWidth; }
911dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    uint32_t getViewportHeight() const { return mRenderTarget.viewportHeight; }
921dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik
931dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    // simple draw methods, to be used for end frame decoration
941dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    void drawRect(float left, float top, float right, float bottom, const SkPaint* paint) {
951bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck        float ltrb[4] = {left, top, right, bottom};
961dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik        drawRects(ltrb, 4, paint);
971dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    }
981dfa0704964c17e45775b9e01f1fa0b1a10774f7Chris Craik    void drawRects(const float* rects, int count, const SkPaint* paint);
991bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck
100419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craikprotected:
101419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    GlopReceiver mGlopReceiver;
1021bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck
1035854b34881b1a747ac80b5077869ef270a92b1f4Chris Craikprivate:
104419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds,
1051bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck                                    const ClipBase* clip, const Glop& glop) {
106419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik        renderer.renderGlopImpl(dirtyBounds, clip, glop);
107419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    }
108419a1e7ef53468e494d21c66ea7f63c0c522d208Chris Craik    void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop);
1095854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    void setViewport(uint32_t width, uint32_t height);
11098787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    void clearColorBuffer(const Rect& clearRect);
111e4db79de127cfe961195f52907af8451026eaa20Chris Craik    void prepareRender(const Rect* dirtyBounds, const ClipBase* clip);
112e4db79de127cfe961195f52907af8451026eaa20Chris Craik    void setupStencilRectList(const ClipBase* clip);
113e4db79de127cfe961195f52907af8451026eaa20Chris Craik    void setupStencilRegion(const ClipBase* clip);
114e4db79de127cfe961195f52907af8451026eaa20Chris Craik    void setupStencilQuads(std::vector<Vertex>& quadVertices, int incrementThreshold);
115b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1165854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    RenderState& mRenderState;
1175854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    Caches& mCaches;
1185854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    bool mOpaque;
11907ae505d4045e2b1ae501e87560984dae06f9dd8Romain Guy    bool mWideColorGamut;
1205854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    bool mHasDrawn = false;
121b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik
1225854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // render target state - setup by start/end layer/frame
1235854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    // only valid to use in between start/end pairs.
1245854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    struct {
125e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // If not drawing to a layer: fbo = 0, offscreenBuffer = null,
126e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // Otherwise these refer to currently painting layer's state
1275854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        GLuint frameBufferId = 0;
1285854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik        OffscreenBuffer* offscreenBuffer = nullptr;
129e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik
130e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // Used when drawing to a layer and using stencil clipping. otherwise null.
131e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        RenderBuffer* stencil = nullptr;
132e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik
133e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // value representing the ClipRectList* or ClipRegion* currently stored in
134e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // the stencil of the current render target
135e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        const ClipBase* lastStencilClip = nullptr;
136e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik
137e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // Size of renderable region in current render target - for layers, may not match actual
138e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik        // bounds of FBO texture. offscreenBuffer->texture has this information.
139818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik        uint32_t viewportWidth = 0;
140818c9fbf1d76d5df19253ba4eb964efa939ec9ecChris Craik        uint32_t viewportHeight = 0;
141e5b50197e870aa6d22c3893f5d25f4279f06e5c3Chris Craik
142b565df13a9e5c7b1d7d93bdfa4a793752d66d3ccChris Craik        Matrix4 orthoMatrix;
1435854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik    } mRenderTarget;
14498787e6c9b2c10b1ab7820bdac168686025b924aChris Craik
14598787e6c9b2c10b1ab7820bdac168686025b924aChris Craik    const LightInfo mLightInfo;
1465854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik};
1475854b34881b1a747ac80b5077869ef270a92b1f4Chris Craik
1481bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace uirenderer
1491bcacfdcab0eaa0cee92bd7f5a1b5e271dd68e52John Reck};  // namespace android
150