1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CANVASCONTEXT_H_
18 #define CANVASCONTEXT_H_
19 
20 #include "DamageAccumulator.h"
21 #include "IContextFactory.h"
22 #include "FrameInfo.h"
23 #include "FrameInfoVisualizer.h"
24 #include "RenderNode.h"
25 #include "utils/RingBuffer.h"
26 #include "renderthread/RenderTask.h"
27 #include "renderthread/RenderThread.h"
28 
29 #include <cutils/compiler.h>
30 #include <EGL/egl.h>
31 #include <SkBitmap.h>
32 #include <SkRect.h>
33 #include <utils/Functor.h>
34 #include <utils/Vector.h>
35 
36 #include <set>
37 #include <string>
38 
39 namespace android {
40 namespace uirenderer {
41 
42 class AnimationContext;
43 class DeferredLayerUpdater;
44 class OpenGLRenderer;
45 class Rect;
46 class Layer;
47 class RenderState;
48 
49 namespace renderthread {
50 
51 class EglManager;
52 
53 enum SwapBehavior {
54     kSwap_default,
55     kSwap_discardBuffer,
56 };
57 
58 // This per-renderer class manages the bridge between the global EGL context
59 // and the render surface.
60 // TODO: Rename to Renderer or some other per-window, top-level manager
61 class CanvasContext : public IFrameCallback {
62 public:
63     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
64             IContextFactory* contextFactory);
65     virtual ~CanvasContext();
66 
67     // Won't take effect until next EGLSurface creation
68     void setSwapBehavior(SwapBehavior swapBehavior);
69 
70     bool initialize(ANativeWindow* window);
71     void updateSurface(ANativeWindow* window);
72     bool pauseSurface(ANativeWindow* window);
hasSurface()73     bool hasSurface() { return mNativeWindow.get(); }
74 
75     void setup(int width, int height, float lightRadius,
76             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
77     void setLightCenter(const Vector3& lightCenter);
78     void setOpaque(bool opaque);
79     void makeCurrent();
80     void processLayerUpdate(DeferredLayerUpdater* layerUpdater);
81     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo, int64_t syncQueued);
82     void draw();
83     void destroy();
84 
85     // IFrameCallback, Chroreographer-driven frame callback entry point
86     virtual void doFrame() override;
87 
88     void buildLayer(RenderNode* node);
89     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
90     void markLayerInUse(RenderNode* node);
91 
92     void destroyHardwareResources();
93     static void trimMemory(RenderThread& thread, int level);
94 
95     static void invokeFunctor(RenderThread& thread, Functor* functor);
96 
97     void runWithGlContext(RenderTask* task);
98 
99     Layer* createTextureLayer();
100 
101     ANDROID_API static void setTextureAtlas(RenderThread& thread,
102             const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
103 
104     void stopDrawing();
105     void notifyFramePending();
106 
profiler()107     FrameInfoVisualizer& profiler() { return mProfiler; }
108 
109     void dumpFrames(int fd);
110     void resetFrameStats();
111 
setName(const std::string && name)112     void setName(const std::string&& name) { mName = name; }
name()113     const std::string& name() { return mName; }
114 
115 private:
116     friend class RegisterFrameCallbackTask;
117     // TODO: Replace with something better for layer & other GL object
118     // lifecycle tracking
119     friend class android::uirenderer::RenderState;
120 
121     void setSurface(ANativeWindow* window);
122     void swapBuffers(const SkRect& dirty, EGLint width, EGLint height);
123     void requireSurface();
124 
125     void freePrefetechedLayers();
126 
127     RenderThread& mRenderThread;
128     EglManager& mEglManager;
129     sp<ANativeWindow> mNativeWindow;
130     EGLSurface mEglSurface = EGL_NO_SURFACE;
131     bool mBufferPreserved = false;
132     SwapBehavior mSwapBehavior = kSwap_default;
133 
134     bool mOpaque;
135     OpenGLRenderer* mCanvas = nullptr;
136     bool mHaveNewSurface = false;
137     DamageAccumulator mDamageAccumulator;
138     std::unique_ptr<AnimationContext> mAnimationContext;
139 
140     const sp<RenderNode> mRootRenderNode;
141 
142     FrameInfo* mCurrentFrameInfo = nullptr;
143     // Ring buffer large enough for 2 seconds worth of frames
144     RingBuffer<FrameInfo, 120> mFrames;
145     std::string mName;
146     JankTracker mJankTracker;
147     FrameInfoVisualizer mProfiler;
148 
149     std::set<RenderNode*> mPrefetechedLayers;
150 };
151 
152 } /* namespace renderthread */
153 } /* namespace uirenderer */
154 } /* namespace android */
155 #endif /* CANVASCONTEXT_H_ */
156