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
14struct GrCachedLayer;
15class GrReplacements;
16class SkGpuDevice;
17struct SkRect;
18
19class GrHoistedLayer {
20public:
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
34class GrLayerHoister {
35public:
36
37    /** Find the layers in 'topLevelPicture' that can be atlased. Note that the discovered
38        layers can be inside nested sub-pictures.
39        @param context    Owner of the layer cache (the source of new layers)
40        @param topLevelPicture The top-level picture that is about to be rendered
41        @param initialMat  The CTM of the canvas into which the layers will be drawn
42        @param query       The rectangle that is about to be drawn.
43        @param atlasedNeedRendering Out parameter storing the layers that
44                                    should be hoisted to the atlas
45        @param recycled    Out parameter storing layers that are atlased but do not need rendering
46        @param numSamples  The number if MSAA samples required
47        */
48    static void FindLayersToAtlas(GrContext* context,
49                                  const SkPicture* topLevelPicture,
50                                  const SkMatrix& initialMat,
51                                  const SkRect& query,
52                                  SkTDArray<GrHoistedLayer>* atlasedNeedRendering,
53                                  SkTDArray<GrHoistedLayer>* recycled,
54                                  int numSamples);
55
56    /** Find the layers in 'topLevelPicture' that need hoisting. Note that the discovered
57        layers can be inside nested sub-pictures.
58        @param context    Owner of the layer cache (the source of new layers)
59        @param topLevelPicture The top-level picture that is about to be rendered
60        @param initialMat  The CTM of the canvas into which the layers will be drawn
61        @param query       The rectangle that is about to be drawn.
62        @param needRendering Out parameter storing the layers that need rendering.
63                             This should never include atlased layers.
64        @param recycled    Out parameter storing layers that need hoisting but not rendering
65        @param numSamples  The number if MSAA samples required
66    */
67    static void FindLayersToHoist(GrContext* context,
68                                  const SkPicture* topLevelPicture,
69                                  const SkMatrix& initialMat,
70                                  const SkRect& query,
71                                  SkTDArray<GrHoistedLayer>* needRendering,
72                                  SkTDArray<GrHoistedLayer>* recycled,
73                                  int numSamples);
74
75    /** Draw the specified layers into the atlas.
76        @param context      Owner of the layer cache (and thus the layers)
77        @param layers       The layers to be drawn into the atlas
78    */
79    static void DrawLayersToAtlas(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
80
81    /** Draw the specified layers into their own individual textures.
82        @param context      Owner of the layer cache (and thus the layers)
83        @param layers       The layers to be drawn
84    */
85    static void DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
86
87    /** Convert all the layers in 'layers' into replacement objects in 'replacements'.
88        @param layers       The hoisted layers
89        @param replacements Replacement object that will be used for a replacement draw
90    */
91    static void ConvertLayersToReplacements(const SkPicture* topLevelPicture,
92                                            const SkTDArray<GrHoistedLayer>& layers,
93                                            GrReplacements* replacements);
94
95    /** Unlock a group of layers in the layer cache.
96        @param context    Owner of the layer cache (and thus the layers)
97        @param layers     Unneeded layers in the atlas
98    */
99    static void UnlockLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);
100
101    /** Forceably remove all cached layers and release the atlas. Useful for debugging and timing.
102        This is only functional when GR_CACHE_HOISTED_LAYERS is set to 1 in GrLayerCache.h
103        @param context    Owner of the layer cache (and thus the layers)
104     */
105    static void PurgeCache(GrContext* context);
106
107private:
108    /** Update the GrTexture in 'layer' with its filtered version
109        @param context    Owner of the layer cache (and thus the layers)
110        @param device     Required by the filtering code
111        @param info       Layer info for a layer needing filtering prior to being composited
112     */
113    static void FilterLayer(GrContext* context, SkGpuDevice* device, const GrHoistedLayer& info);
114
115};
116
117#endif
118