CanvasContext.h revision 06f5bc70a667a02b14e31d3f53f91d3661e30666
1e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck/*
2e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Copyright (C) 2014 The Android Open Source Project
3e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
4e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * you may not use this file except in compliance with the License.
6e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * You may obtain a copy of the License at
7e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
8e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck *
10e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * Unless required by applicable law or agreed to in writing, software
11e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * See the License for the specific language governing permissions and
14e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck * limitations under the License.
15e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck */
16e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
17e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#ifndef CANVASCONTEXT_H_
18e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#define CANVASCONTEXT_H_
19e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
20e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "DamageAccumulator.h"
21e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "FrameInfo.h"
22e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "FrameInfoVisualizer.h"
23e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "FrameStatsReporter.h"
24e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "IContextFactory.h"
25e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "LayerUpdateQueue.h"
26e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "RenderNode.h"
27e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "utils/RingBuffer.h"
28e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "renderthread/RenderTask.h"
29e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "renderthread/RenderThread.h"
30e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
31e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#if HWUI_NEW_OPS
32e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "BakedOpDispatcher.h"
33e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include "BakedOpRenderer.h"
34e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#endif
35e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
36e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <cutils/compiler.h>
37e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <EGL/egl.h>
38496b8770c19c573299e4be525e877acc977a2dadJohn Reck#include <SkBitmap.h>
39496b8770c19c573299e4be525e877acc977a2dadJohn Reck#include <SkRect.h>
40e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <utils/Functor.h>
41e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
42e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <set>
43e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <string>
44e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#include <vector>
45e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
46e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Recknamespace android {
47e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Recknamespace uirenderer {
4852244fff29042926e21fa897ef5ab11148e35299John Reck
4952244fff29042926e21fa897ef5ab11148e35299John Reckclass AnimationContext;
5052244fff29042926e21fa897ef5ab11148e35299John Reckclass DeferredLayerUpdater;
5152244fff29042926e21fa897ef5ab11148e35299John Reckclass OpenGLRenderer;
5252244fff29042926e21fa897ef5ab11148e35299John Reckclass Rect;
5352244fff29042926e21fa897ef5ab11148e35299John Reckclass Layer;
5452244fff29042926e21fa897ef5ab11148e35299John Reckclass RenderState;
5552244fff29042926e21fa897ef5ab11148e35299John Reck
5652244fff29042926e21fa897ef5ab11148e35299John Recknamespace renderthread {
5752244fff29042926e21fa897ef5ab11148e35299John Reck
58e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckclass EglManager;
5952244fff29042926e21fa897ef5ab11148e35299John Reck
6052244fff29042926e21fa897ef5ab11148e35299John Reckenum SwapBehavior {
6152244fff29042926e21fa897ef5ab11148e35299John Reck    kSwap_default,
6252244fff29042926e21fa897ef5ab11148e35299John Reck    kSwap_discardBuffer,
6352244fff29042926e21fa897ef5ab11148e35299John Reck};
64e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
65ff941dcd815021bb20d6504eb486acb1e50592c3John Reck// This per-renderer class manages the bridge between the global EGL context
6652244fff29042926e21fa897ef5ab11148e35299John Reck// and the render surface.
6752244fff29042926e21fa897ef5ab11148e35299John Reck// TODO: Rename to Renderer or some other per-window, top-level manager
6852244fff29042926e21fa897ef5ab11148e35299John Reckclass CanvasContext : public IFrameCallback {
6952244fff29042926e21fa897ef5ab11148e35299John Reckpublic:
7052244fff29042926e21fa897ef5ab11148e35299John Reck    CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
7152244fff29042926e21fa897ef5ab11148e35299John Reck            IContextFactory* contextFactory);
72e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    virtual ~CanvasContext();
7352244fff29042926e21fa897ef5ab11148e35299John Reck
7452244fff29042926e21fa897ef5ab11148e35299John Reck    // Won't take effect until next EGLSurface creation
7552244fff29042926e21fa897ef5ab11148e35299John Reck    void setSwapBehavior(SwapBehavior swapBehavior);
7652244fff29042926e21fa897ef5ab11148e35299John Reck
7752244fff29042926e21fa897ef5ab11148e35299John Reck    void initialize(ANativeWindow* window);
7852244fff29042926e21fa897ef5ab11148e35299John Reck    void updateSurface(ANativeWindow* window);
7952244fff29042926e21fa897ef5ab11148e35299John Reck    bool pauseSurface(ANativeWindow* window);
80e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool hasSurface() { return mNativeWindow.get(); }
8152244fff29042926e21fa897ef5ab11148e35299John Reck
8252244fff29042926e21fa897ef5ab11148e35299John Reck    void setup(int width, int height, float lightRadius,
8352244fff29042926e21fa897ef5ab11148e35299John Reck            uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
8452244fff29042926e21fa897ef5ab11148e35299John Reck    void setLightCenter(const Vector3& lightCenter);
8552244fff29042926e21fa897ef5ab11148e35299John Reck    void setOpaque(bool opaque);
8652244fff29042926e21fa897ef5ab11148e35299John Reck    void makeCurrent();
8752244fff29042926e21fa897ef5ab11148e35299John Reck    void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
8852244fff29042926e21fa897ef5ab11148e35299John Reck            int64_t syncQueued, RenderNode* target);
8952244fff29042926e21fa897ef5ab11148e35299John Reck    void draw();
9052244fff29042926e21fa897ef5ab11148e35299John Reck    void destroy();
9152244fff29042926e21fa897ef5ab11148e35299John Reck
92ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    // IFrameCallback, Choreographer-driven frame callback entry point
9352244fff29042926e21fa897ef5ab11148e35299John Reck    virtual void doFrame() override;
9452244fff29042926e21fa897ef5ab11148e35299John Reck    void prepareAndDraw(RenderNode* node);
95ff941dcd815021bb20d6504eb486acb1e50592c3John Reck
9652244fff29042926e21fa897ef5ab11148e35299John Reck    void buildLayer(RenderNode* node);
9752244fff29042926e21fa897ef5ab11148e35299John Reck    bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
9852244fff29042926e21fa897ef5ab11148e35299John Reck    void markLayerInUse(RenderNode* node);
9952244fff29042926e21fa897ef5ab11148e35299John Reck
10052244fff29042926e21fa897ef5ab11148e35299John Reck    void destroyHardwareResources();
101ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    static void trimMemory(RenderThread& thread, int level);
10252244fff29042926e21fa897ef5ab11148e35299John Reck
103ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    static void invokeFunctor(RenderThread& thread, Functor* functor);
10452244fff29042926e21fa897ef5ab11148e35299John Reck
10552244fff29042926e21fa897ef5ab11148e35299John Reck    void runWithGlContext(RenderTask* task);
10652244fff29042926e21fa897ef5ab11148e35299John Reck
107e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    Layer* createTextureLayer();
10852244fff29042926e21fa897ef5ab11148e35299John Reck
10952244fff29042926e21fa897ef5ab11148e35299John Reck    ANDROID_API static void setTextureAtlas(RenderThread& thread,
110ff941dcd815021bb20d6504eb486acb1e50592c3John Reck            const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
11152244fff29042926e21fa897ef5ab11148e35299John Reck
11252244fff29042926e21fa897ef5ab11148e35299John Reck    void stopDrawing();
113ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    void notifyFramePending();
114ff941dcd815021bb20d6504eb486acb1e50592c3John Reck
11552244fff29042926e21fa897ef5ab11148e35299John Reck    FrameInfoVisualizer& profiler() { return mProfiler; }
116e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
117e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void dumpFrames(int fd);
118e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void resetFrameStats();
119c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck
120c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    void setName(const std::string&& name) { mName = name; }
121c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    const std::string& name() { return mName; }
122c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck
123c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    void serializeDisplayListTree();
124ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
125e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    void addRenderNode(RenderNode* node, bool placeFront) {
126ff941dcd815021bb20d6504eb486acb1e50592c3John Reck        int pos = placeFront ? 0 : static_cast<int>(mRenderNodes.size());
127e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRenderNodes.emplace(mRenderNodes.begin() + pos, node);
128e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
129e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
130ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    void removeRenderNode(RenderNode* node) {
131ff941dcd815021bb20d6504eb486acb1e50592c3John Reck        mRenderNodes.erase(std::remove(mRenderNodes.begin(), mRenderNodes.end(), node),
132ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette                mRenderNodes.end());
133ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    }
134ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
135ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    void setContentDrawBounds(int left, int top, int right, int bottom) {
136ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette        mContentDrawBounds.set(left, top, right, bottom);
137ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    }
138ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
139ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    RenderState& getRenderState() {
140ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette        return mRenderThread.renderState();
141ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    }
142ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
143ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    void addFrameStatsObserver(FrameStatsObserver* observer) {
144315c329544d7c593d1072b071cbb92d9afe74021John Reck        if (mFrameStatsReporter.get() == nullptr) {
145315c329544d7c593d1072b071cbb92d9afe74021John Reck            mFrameStatsReporter.reset(new FrameStatsReporter());
146315c329544d7c593d1072b071cbb92d9afe74021John Reck        }
147ff941dcd815021bb20d6504eb486acb1e50592c3John Reck
148315c329544d7c593d1072b071cbb92d9afe74021John Reck        mFrameStatsReporter->addObserver(observer);
149315c329544d7c593d1072b071cbb92d9afe74021John Reck    }
150315c329544d7c593d1072b071cbb92d9afe74021John Reck
151315c329544d7c593d1072b071cbb92d9afe74021John Reck    void removeFrameStatsObserver(FrameStatsObserver* observer) {
1528d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck        if (mFrameStatsReporter.get() != nullptr) {
1538d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck            mFrameStatsReporter->removeObserver(observer);
1548d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck            if (!mFrameStatsReporter->hasObservers()) {
1558d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck                mFrameStatsReporter.reset(nullptr);
1568d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck            }
15768bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck        }
15868bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    }
15968bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck
16068bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    long getDroppedFrameReportCount() {
16168bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck        if (mFrameStatsReporter.get() != nullptr) {
162496b8770c19c573299e4be525e877acc977a2dadJohn Reck            return mFrameStatsReporter->getDroppedReports();
163496b8770c19c573299e4be525e877acc977a2dadJohn Reck        }
164e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
165e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        return 0;
166e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    }
167e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
168e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reckprivate:
169e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    friend class RegisterFrameCallbackTask;
170e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    // TODO: Replace with something better for layer & other GL object
171496b8770c19c573299e4be525e877acc977a2dadJohn Reck    // lifecycle tracking
172ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    friend class android::uirenderer::RenderState;
173ff941dcd815021bb20d6504eb486acb1e50592c3John Reck
174ff941dcd815021bb20d6504eb486acb1e50592c3John Reck    void setSurface(ANativeWindow* window);
175c6b3264e16f1d2b72e7f9508559981ce9970157cJohn Reck    void requireSurface();
176ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
177ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    void freePrefetechedLayers();
178ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette
179ad2f8e334f3ef22d3e412b0660a2e1f996f94116Alan Viverette    EGLint mLastFrameWidth = 0;
180315c329544d7c593d1072b071cbb92d9afe74021John Reck    EGLint mLastFrameHeight = 0;
1818d8af3c1b768d590754d657a7d1242dcb462454bJohn Reck
18268bfe0a37a0dcef52abd81688d8520c5d16e1a85John Reck    RenderThread& mRenderThread;
183496b8770c19c573299e4be525e877acc977a2dadJohn Reck    EglManager& mEglManager;
184e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    sp<ANativeWindow> mNativeWindow;
185e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    EGLSurface mEglSurface = EGL_NO_SURFACE;
186e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool mBufferPreserved = false;
187e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    SwapBehavior mSwapBehavior = kSwap_default;
188e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    struct SwapHistory {
189e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        SkRect damage;
190e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        nsecs_t vsyncTime;
191e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        nsecs_t swapTime;
192e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    };
193e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
194e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    RingBuffer<SwapHistory, 3> mSwapHistory;
195e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
196e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool mOpaque;
197e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    OpenGLRenderer* mCanvas = nullptr;
198e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#if HWUI_NEW_OPS
199e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    BakedOpRenderer::LightInfo mLightInfo;
200e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    Vector3 mLightCenter = { 0, 0, 0 };
201e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck#endif
202e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck
203e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    bool mHaveNewSurface = false;
204e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    DamageAccumulator mDamageAccumulator;
205e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    LayerUpdateQueue mLayerUpdateQueue;
206    std::unique_ptr<AnimationContext> mAnimationContext;
207
208    std::vector< sp<RenderNode> > mRenderNodes;
209
210    FrameInfo* mCurrentFrameInfo = nullptr;
211    // Ring buffer large enough for 2 seconds worth of frames
212    RingBuffer<FrameInfo, 120> mFrames;
213    std::string mName;
214    JankTracker mJankTracker;
215    FrameInfoVisualizer mProfiler;
216    std::unique_ptr<FrameStatsReporter> mFrameStatsReporter;
217
218    std::set<RenderNode*> mPrefetechedLayers;
219
220    // Stores the bounds of the main content.
221    Rect mContentDrawBounds;
222};
223
224} /* namespace renderthread */
225} /* namespace uirenderer */
226} /* namespace android */
227#endif /* CANVASCONTEXT_H_ */
228