Home | History | Annotate | Download | only in renderthread
      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 "FrameInfo.h"
     22 #include "FrameInfoVisualizer.h"
     23 #include "FrameMetricsReporter.h"
     24 #include "IContextFactory.h"
     25 #include "LayerUpdateQueue.h"
     26 #include "RenderNode.h"
     27 #include "thread/Task.h"
     28 #include "thread/TaskProcessor.h"
     29 #include "utils/RingBuffer.h"
     30 #include "renderthread/RenderTask.h"
     31 #include "renderthread/RenderThread.h"
     32 
     33 #if HWUI_NEW_OPS
     34 #include "BakedOpDispatcher.h"
     35 #include "BakedOpRenderer.h"
     36 #include "FrameBuilder.h"
     37 #endif
     38 
     39 #include <cutils/compiler.h>
     40 #include <EGL/egl.h>
     41 #include <SkBitmap.h>
     42 #include <SkRect.h>
     43 #include <utils/Functor.h>
     44 #include <gui/Surface.h>
     45 
     46 #include <functional>
     47 #include <set>
     48 #include <string>
     49 #include <vector>
     50 
     51 namespace android {
     52 namespace uirenderer {
     53 
     54 class AnimationContext;
     55 class DeferredLayerUpdater;
     56 class OpenGLRenderer;
     57 class Rect;
     58 class Layer;
     59 class RenderState;
     60 
     61 namespace renderthread {
     62 
     63 class EglManager;
     64 
     65 enum SwapBehavior {
     66     kSwap_default,
     67     kSwap_discardBuffer,
     68 };
     69 
     70 // This per-renderer class manages the bridge between the global EGL context
     71 // and the render surface.
     72 // TODO: Rename to Renderer or some other per-window, top-level manager
     73 class CanvasContext : public IFrameCallback {
     74 public:
     75     CanvasContext(RenderThread& thread, bool translucent, RenderNode* rootRenderNode,
     76             IContextFactory* contextFactory);
     77     virtual ~CanvasContext();
     78 
     79     // Won't take effect until next EGLSurface creation
     80     void setSwapBehavior(SwapBehavior swapBehavior);
     81 
     82     void initialize(Surface* surface);
     83     void updateSurface(Surface* surface);
     84     bool pauseSurface(Surface* surface);
     85     void setStopped(bool stopped);
     86     bool hasSurface() { return mNativeSurface.get(); }
     87 
     88     void setup(int width, int height, float lightRadius,
     89             uint8_t ambientShadowAlpha, uint8_t spotShadowAlpha);
     90     void setLightCenter(const Vector3& lightCenter);
     91     void setOpaque(bool opaque);
     92     bool makeCurrent();
     93     void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
     94             int64_t syncQueued, RenderNode* target);
     95     void draw();
     96     void destroy(TreeObserver* observer);
     97 
     98     // IFrameCallback, Choreographer-driven frame callback entry point
     99     virtual void doFrame() override;
    100     void prepareAndDraw(RenderNode* node);
    101 
    102     void buildLayer(RenderNode* node, TreeObserver* observer);
    103     bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
    104     void markLayerInUse(RenderNode* node);
    105 
    106     void destroyHardwareResources(TreeObserver* observer);
    107     static void trimMemory(RenderThread& thread, int level);
    108 
    109     static void invokeFunctor(RenderThread& thread, Functor* functor);
    110 
    111     void runWithGlContext(RenderTask* task);
    112 
    113     Layer* createTextureLayer();
    114 
    115     ANDROID_API static void setTextureAtlas(RenderThread& thread,
    116             const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize);
    117 
    118     void stopDrawing();
    119     void notifyFramePending();
    120 
    121     FrameInfoVisualizer& profiler() { return mProfiler; }
    122 
    123     void dumpFrames(int fd);
    124     void resetFrameStats();
    125 
    126     void setName(const std::string&& name) { mName = name; }
    127     const std::string& name() { return mName; }
    128 
    129     void serializeDisplayListTree();
    130 
    131     void addRenderNode(RenderNode* node, bool placeFront) {
    132         int pos = placeFront ? 0 : static_cast<int>(mRenderNodes.size());
    133         mRenderNodes.emplace(mRenderNodes.begin() + pos, node);
    134     }
    135 
    136     void removeRenderNode(RenderNode* node) {
    137         mRenderNodes.erase(std::remove(mRenderNodes.begin(), mRenderNodes.end(), node),
    138                 mRenderNodes.end());
    139     }
    140 
    141     void setContentDrawBounds(int left, int top, int right, int bottom) {
    142         mContentDrawBounds.set(left, top, right, bottom);
    143     }
    144 
    145     RenderState& getRenderState() {
    146         return mRenderThread.renderState();
    147     }
    148 
    149     void addFrameMetricsObserver(FrameMetricsObserver* observer) {
    150         if (mFrameMetricsReporter.get() == nullptr) {
    151             mFrameMetricsReporter.reset(new FrameMetricsReporter());
    152         }
    153 
    154         mFrameMetricsReporter->addObserver(observer);
    155     }
    156 
    157     void removeFrameMetricsObserver(FrameMetricsObserver* observer) {
    158         if (mFrameMetricsReporter.get() != nullptr) {
    159             mFrameMetricsReporter->removeObserver(observer);
    160             if (!mFrameMetricsReporter->hasObservers()) {
    161                 mFrameMetricsReporter.reset(nullptr);
    162             }
    163         }
    164     }
    165 
    166     // Used to queue up work that needs to be completed before this frame completes
    167     ANDROID_API void enqueueFrameWork(std::function<void()>&& func);
    168 
    169     ANDROID_API int64_t getFrameNumber();
    170 
    171 private:
    172     friend class RegisterFrameCallbackTask;
    173     // TODO: Replace with something better for layer & other GL object
    174     // lifecycle tracking
    175     friend class android::uirenderer::RenderState;
    176 
    177     void setSurface(Surface* window);
    178 
    179     void freePrefetchedLayers(TreeObserver* observer);
    180 
    181     void waitOnFences();
    182 
    183     bool isSwapChainStuffed();
    184 
    185     EGLint mLastFrameWidth = 0;
    186     EGLint mLastFrameHeight = 0;
    187 
    188     RenderThread& mRenderThread;
    189     EglManager& mEglManager;
    190     sp<Surface> mNativeSurface;
    191     EGLSurface mEglSurface = EGL_NO_SURFACE;
    192     // stopped indicates the CanvasContext will reject actual redraw operations,
    193     // and defer repaint until it is un-stopped
    194     bool mStopped = false;
    195     // CanvasContext is dirty if it has received an update that it has not
    196     // painted onto its surface.
    197     bool mIsDirty = false;
    198     bool mBufferPreserved = false;
    199     SwapBehavior mSwapBehavior = kSwap_default;
    200     struct SwapHistory {
    201         SkRect damage;
    202         nsecs_t vsyncTime;
    203         nsecs_t swapCompletedTime;
    204         nsecs_t dequeueDuration;
    205         nsecs_t queueDuration;
    206     };
    207 
    208     RingBuffer<SwapHistory, 3> mSwapHistory;
    209     int64_t mFrameNumber = -1;
    210 
    211     // last vsync for a dropped frame due to stuffed queue
    212     nsecs_t mLastDropVsync = 0;
    213 
    214     bool mOpaque;
    215 #if HWUI_NEW_OPS
    216     BakedOpRenderer::LightInfo mLightInfo;
    217     FrameBuilder::LightGeometry mLightGeometry = { {0, 0, 0}, 0 };
    218 #else
    219     OpenGLRenderer* mCanvas = nullptr;
    220 #endif
    221 
    222     bool mHaveNewSurface = false;
    223     DamageAccumulator mDamageAccumulator;
    224     LayerUpdateQueue mLayerUpdateQueue;
    225     std::unique_ptr<AnimationContext> mAnimationContext;
    226 
    227     std::vector< sp<RenderNode> > mRenderNodes;
    228 
    229     FrameInfo* mCurrentFrameInfo = nullptr;
    230     // Ring buffer large enough for 2 seconds worth of frames
    231     RingBuffer<FrameInfo, 120> mFrames;
    232     std::string mName;
    233     JankTracker mJankTracker;
    234     FrameInfoVisualizer mProfiler;
    235     std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
    236 
    237     std::set<RenderNode*> mPrefetchedLayers;
    238 
    239     // Stores the bounds of the main content.
    240     Rect mContentDrawBounds;
    241 
    242     // TODO: This is really a Task<void> but that doesn't really work
    243     // when Future<> expects to be able to get/set a value
    244     struct FuncTask : public Task<bool> {
    245         std::function<void()> func;
    246     };
    247     class FuncTaskProcessor;
    248 
    249     std::vector< sp<FuncTask> > mFrameFences;
    250     sp<TaskProcessor<bool> > mFrameWorkProcessor;
    251 };
    252 
    253 } /* namespace renderthread */
    254 } /* namespace uirenderer */
    255 } /* namespace android */
    256 #endif /* CANVASCONTEXT_H_ */
    257