10df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger/*
20df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * Copyright (C) 2016 The Android Open Source Project
30df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger *
40df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License");
50df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * you may not use this file except in compliance with the License.
60df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * You may obtain a copy of the License at
70df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger *
80df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger *      http://www.apache.org/licenses/LICENSE-2.0
90df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger *
100df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * Unless required by applicable law or agreed to in writing, software
110df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS,
120df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * See the License for the specific language governing permissions and
140df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * limitations under the License.
150df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger */
160df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
170df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#pragma once
180df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
190df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#include "DisplayList.h"
20021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "GLFunctorDrawable.h"
21021693b967a2c5556dddd183eb0247df4079e1adStan Iliev#include "RenderNodeDrawable.h"
220df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
230df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#include <deque>
240df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger#include <SkLiteDL.h>
25ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger#include <SkLiteRecorder.h>
260df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
270df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergernamespace android {
280df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergernamespace uirenderer {
29db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev
30db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Ilievclass Outline;
31db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev
32021693b967a2c5556dddd183eb0247df4079e1adStan Ilievnamespace skiapipeline {
330df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
340df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger/**
350df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * This class is intended to be self contained, but still subclasses from
360df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * DisplayList to make it easier to support switching between the two at
370df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * runtime.  The downside of this inheritance is that we pay for the overhead
380df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger * of the parent class construction/destruction without any real benefit.
390df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger */
400df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergerclass SkiaDisplayList : public DisplayList {
410df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenbergerpublic:
42ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    SkiaDisplayList() { SkASSERT(projectionReceiveIndex == -1); }
430df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    virtual ~SkiaDisplayList() {
440df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        /* Given that we are using a LinearStdAllocator to store some of the
450df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger         * SkDrawable contents we must ensure that any other object that is
460df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger         * holding a reference to those drawables is destroyed prior to their
470df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger         * deletion.
480df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger         */
49ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger        mDisplayList.reset();
500df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
510df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
520df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
530df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * This resets the DisplayList so that it behaves as if the object were newly
54ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger     * constructed.  The reuse avoids any overhead associated with destroying
55ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger     * the SkLiteDL as well as the deques and vectors.
560df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
57ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    void reset();
580df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
590df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
600df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * Use the linear allocator to create any SkDrawables needed by the display
610df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * list. This could be dangerous as these objects are ref-counted, so we
620df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * need to monitor that they don't extend beyond the lifetime of the class
630df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * that creates them.
640df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
650df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    template<class T, typename... Params>
660df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    SkDrawable* allocateDrawable(Params&&... params) {
670df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger        return allocator.create<T>(std::forward<Params>(params)...);
680df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    }
690df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
700df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    bool isSkiaDL() const override { return true; }
710df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
720df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
730df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * Returns true if the DisplayList does not have any recorded content
740df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
75ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    bool isEmpty() const override { return mDisplayList.empty(); }
760df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
770df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
780df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * Returns true if this list directly contains a GLFunctor drawing command.
790df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
800df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    bool hasFunctor() const override { return !mChildFunctors.empty(); }
810df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
820df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
830df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * Returns true if this list directly contains a VectorDrawable drawing command.
840df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
850df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    bool hasVectorDrawables() const override { return !mVectorDrawables.empty(); }
860df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
870df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
880df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * Attempts to reset and reuse this DisplayList.
890df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *
900df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * @return true if the displayList will be reused and therefore should not be deleted
910df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
920df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    bool reuseDisplayList(RenderNode* node, renderthread::CanvasContext* context) override;
930df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
940df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
950df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * ONLY to be called by RenderNode::syncDisplayList so that we can notify any
960df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * contained VectorDrawables or GLFunctors to sync their state.
970df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *
980df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * NOTE: This function can be folded into RenderNode when we no longer need
990df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *       to subclass from DisplayList
1000df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
1010df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    void syncContents() override;
1020df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1030df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
1040df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * ONLY to be called by RenderNode::prepareTree in order to prepare this
1050df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * list while the UI thread is blocked.  Here we can upload mutable bitmaps
1060df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * and notify our parent if any of our content has been invalidated and in
1070df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * need of a redraw.  If the renderNode has any children then they are also
1080df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * call in order to prepare them.
1090df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *
1100df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * @return true if any content change requires the node to be invalidated
1110df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *
1120df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * NOTE: This function can be folded into RenderNode when we no longer need
1130df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *       to subclass from DisplayList
1140df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
1150df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1162de950d5a8b47c7b4648ada1b1260ce4b7342798John Reck    bool prepareListAndChildren(TreeObserver& observer, TreeInfo& info, bool functorsNeedLayer,
1172de950d5a8b47c7b4648ada1b1260ce4b7342798John Reck            std::function<void(RenderNode*, TreeObserver&, TreeInfo&, bool)> childFn) override;
1180df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1190df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
1200df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     *  Calls the provided function once for each child of this DisplayList
1210df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
1220df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    void updateChildren(std::function<void(RenderNode*)> updateFn) override;
1230df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
1240df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    /**
125db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev     *  Returns true if there is a child render node that is a projection receiver.
126db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev     */
127db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    inline bool containsProjectionReceiver() const { return mProjectionReceiver; }
128db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev
129ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    void attachRecorder(SkLiteRecorder* recorder, const SkIRect& bounds) {
130ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger        recorder->reset(&mDisplayList, bounds);
131ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    }
132ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger
133ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    void draw(SkCanvas* canvas) { mDisplayList.draw(canvas); }
134ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger
135d21723704571dba7e69947d92856f22989d53dbfStan Iliev    void output(std::ostream& output, uint32_t level) override;
136d21723704571dba7e69947d92856f22989d53dbfStan Iliev
137db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    /**
1380df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     * We use std::deque here because (1) we need to iterate through these
139ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger     * elements and (2) mDisplayList holds pointers to the elements, so they
140ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger     * cannot relocate.
1410df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger     */
1420df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    std::deque<RenderNodeDrawable> mChildNodes;
1430df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    std::deque<GLFunctorDrawable> mChildFunctors;
1440df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    std::vector<SkImage*> mMutableImages;
1450df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger    std::vector<VectorDrawableRoot*> mVectorDrawables;
146ea1fe9b9d6ff9f0a543489979a0a909acc9ea564Derek Sollenberger    SkLiteDL mDisplayList;
1470df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
148db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //mProjectionReceiver points to a child node (stored in mChildNodes) that is as a projection
149db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //receiver. It is set at record time and used at both prepare and draw tree traversals to
150db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //make sure backward projected nodes are found and drawn immediately after mProjectionReceiver.
151db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    RenderNodeDrawable* mProjectionReceiver = nullptr;
152db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev
153db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //mProjectedOutline is valid only when render node tree is traversed during the draw pass.
154db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //Render nodes that have a child receiver node, will store a pointer to their outline in
155db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //mProjectedOutline. Child receiver node will apply the clip before any backward projected
156db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //node is drawn.
157db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    const Outline* mProjectedOutline = nullptr;
158db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev
159db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //mProjectedReceiverParentMatrix is valid when render node tree is traversed during the draw
160db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //pass. Render nodes that have a child receiver node, will store their matrix in
161db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //mProjectedReceiverParentMatrix. Child receiver node will set the matrix and then clip with the
162db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    //outline of their parent.
163db45a4bfaff1120a9b23073e46a0cc6d39f56023Stan Iliev    SkMatrix mProjectedReceiverParentMatrix;
1640df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger};
1650df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger
166021693b967a2c5556dddd183eb0247df4079e1adStan Iliev}; // namespace skiapipeline
1670df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger}; // namespace uirenderer
1680df6209a02d0ea99d2dff3a46ed9febd5925df4bDerek Sollenberger}; // namespace android
169