1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrLayerHoister_DEFINED
9 #define GrLayerHoister_DEFINED
10 
11 #include "SkPicture.h"
12 #include "SkTDArray.h"
13 
14 struct GrCachedLayer;
15 class GrReplacements;
16 class SkGpuDevice;
17 struct SkRect;
18 
19 class GrHoistedLayer {
20 public:
21     const SkPicture* fPicture;  // the picture that actually contains the layer
22                                 // (not necessarily the top-most picture)
23     GrCachedLayer*   fLayer;
24     SkMatrix         fInitialMat;
25     SkMatrix         fPreMat;
26     SkMatrix         fLocalMat;
27 };
28 
29 // This class collects the layer hoisting functionality in one place.
30 // For each picture rendering:
31 //  FindLayersToHoist should be called once to collect the required layers
32 //  DrawLayers should be called once to render them
33 //  UnlockLayers should be called once to allow the texture resources to be recycled
34 class GrLayerHoister {
35 public:
36     /** Attempt to reattach layers that may have been atlased in the past
37      */
38     static void Begin(GrContext* context);
39 
40     /** Release cache resources
41      */
42     static void End(GrContext* context);
43 
44     /** Find the layers in 'topLevelPicture' that can be atlased. Note that the discovered
45         layers can be inside nested sub-pictures.
46         @param context    Owner of the layer cache (the source of new layers)
47         @param topLevelPicture The top-level picture that is about to be rendered
48         @param initialMat  The CTM of the canvas into which the layers will be drawn
49         @param query       The rectangle that is about to be drawn.
50         @param atlasedNeedRendering Out parameter storing the layers that
51                                     should be hoisted to the atlas
52         @param recycled    Out parameter storing layers that are atlased but do not need rendering
53         @param numSamples  The number if MSAA samples required
54         */
55     static void FindLayersToAtlas(GrContext* context,
56                                   const SkPicture* topLevelPicture,
57                                   const SkMatrix& initialMat,
58                                   const SkRect& query,
59                                   SkTDArray<GrHoistedLayer>* atlasedNeedRendering,
60                                   SkTDArray<GrHoistedLayer>* recycled,
61                                   int numSamples);
62 
63     /** Find the layers in 'topLevelPicture' that need hoisting. Note that the discovered
64         layers can be inside nested sub-pictures.
65         @param context    Owner of the layer cache (the source of new layers)
66         @param topLevelPicture The top-level picture that is about to be rendered
67         @param initialMat  The CTM of the canvas into which the layers will be drawn
68         @param query       The rectangle that is about to be drawn.
69         @param needRendering Out parameter storing the layers that need rendering.
70                              This should never include atlased layers.
71         @param recycled    Out parameter storing layers that need hoisting but not rendering
72         @param numSamples  The number if MSAA samples required
73     */
74     static void FindLayersToHoist(GrContext* context,
75                                   const SkPicture* topLevelPicture,
76                                   const SkMatrix& initialMat,
77                                   const SkRect& query,
78                                   SkTDArray<GrHoistedLayer>* needRendering,
79                                   SkTDArray<GrHoistedLayer>* recycled,
80                                   int numSamples);
81 
82     /** Draw the specified layers into the atlas.
83         @param context      Owner of the layer cache (and thus the layers)
84         @param layers       The layers to be drawn into the atlas
85     */
86     static void DrawLayersToAtlas(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
87 
88     /** Draw the specified layers into their own individual textures.
89         @param context      Owner of the layer cache (and thus the layers)
90         @param layers       The layers to be drawn
91     */
92     static void DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
93 
94     /** Convert all the layers in 'layers' into replacement objects in 'replacements'.
95         @param layers       The hoisted layers
96         @param replacements Replacement object that will be used for a replacement draw
97     */
98     static void ConvertLayersToReplacements(const SkPicture* topLevelPicture,
99                                             const SkTDArray<GrHoistedLayer>& layers,
100                                             GrReplacements* replacements);
101 
102     /** Unlock a group of layers in the layer cache.
103         @param context    Owner of the layer cache (and thus the layers)
104         @param layers     Unneeded layers in the atlas
105     */
106     static void UnlockLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
107 
108     /** Forceably remove all cached layers and release the atlas. Useful for debugging and timing.
109         This is only functional when GR_CACHE_HOISTED_LAYERS is set to 1 in GrLayerCache.h
110         @param context    Owner of the layer cache (and thus the layers)
111      */
112     static void PurgeCache(GrContext* context);
113 
114 private:
115     /** Update the GrTexture in 'layer' with its filtered version
116         @param context    Owner of the layer cache (and thus the layers)
117         @param device     Required by the filtering code
118         @param info       Layer info for a layer needing filtering prior to being composited
119      */
120     static void FilterLayer(GrContext* context, SkGpuDevice* device, const GrHoistedLayer& info);
121 
122 };
123 
124 #endif
125