/*
 * Copyright 2014 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef GrLayerHoister_DEFINED
#define GrLayerHoister_DEFINED

#include "SkPicture.h"
#include "SkTDArray.h"

struct GrCachedLayer;
class GrReplacements;
class SkGpuDevice;
struct SkRect;

class GrHoistedLayer {
public:
    const SkPicture* fPicture;  // the picture that actually contains the layer
                                // (not necessarily the top-most picture)
    GrCachedLayer*   fLayer;
    SkMatrix         fInitialMat;
    SkMatrix         fPreMat;
    SkMatrix         fLocalMat;
};

// This class collects the layer hoisting functionality in one place.
// For each picture rendering:
//  FindLayersToHoist should be called once to collect the required layers
//  DrawLayers should be called once to render them
//  UnlockLayers should be called once to allow the texture resources to be recycled
class GrLayerHoister {
public:

    /** Find the layers in 'topLevelPicture' that can be atlased. Note that the discovered
        layers can be inside nested sub-pictures.
        @param context    Owner of the layer cache (the source of new layers)
        @param topLevelPicture The top-level picture that is about to be rendered
        @param initialMat  The CTM of the canvas into which the layers will be drawn
        @param query       The rectangle that is about to be drawn.
        @param atlasedNeedRendering Out parameter storing the layers that 
                                    should be hoisted to the atlas
        @param recycled    Out parameter storing layers that are atlased but do not need rendering
        @param numSamples  The number if MSAA samples required
        */
    static void FindLayersToAtlas(GrContext* context,
                                  const SkPicture* topLevelPicture,
                                  const SkMatrix& initialMat,
                                  const SkRect& query,
                                  SkTDArray<GrHoistedLayer>* atlasedNeedRendering,
                                  SkTDArray<GrHoistedLayer>* recycled,
                                  int numSamples);

    /** Find the layers in 'topLevelPicture' that need hoisting. Note that the discovered
        layers can be inside nested sub-pictures.
        @param context    Owner of the layer cache (the source of new layers)
        @param topLevelPicture The top-level picture that is about to be rendered
        @param initialMat  The CTM of the canvas into which the layers will be drawn
        @param query       The rectangle that is about to be drawn.
        @param needRendering Out parameter storing the layers that need rendering.
                             This should never include atlased layers.
        @param recycled    Out parameter storing layers that need hoisting but not rendering
        @param numSamples  The number if MSAA samples required
    */
    static void FindLayersToHoist(GrContext* context,
                                  const SkPicture* topLevelPicture,
                                  const SkMatrix& initialMat,
                                  const SkRect& query,
                                  SkTDArray<GrHoistedLayer>* needRendering,
                                  SkTDArray<GrHoistedLayer>* recycled,
                                  int numSamples);

    /** Draw the specified layers into the atlas.
        @param context      Owner of the layer cache (and thus the layers)
        @param layers       The layers to be drawn into the atlas
    */
    static void DrawLayersToAtlas(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);

    /** Draw the specified layers into their own individual textures.
        @param context      Owner of the layer cache (and thus the layers)
        @param layers       The layers to be drawn
    */
    static void DrawLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);

    /** Convert all the layers in 'layers' into replacement objects in 'replacements'.
        @param layers       The hoisted layers
        @param replacements Replacement object that will be used for a replacement draw
    */
    static void ConvertLayersToReplacements(const SkPicture* topLevelPicture, 
                                            const SkTDArray<GrHoistedLayer>& layers,
                                            GrReplacements* replacements);

    /** Unlock a group of layers in the layer cache.
        @param context    Owner of the layer cache (and thus the layers)
        @param layers     Unneeded layers in the atlas
    */
    static void UnlockLayers(GrContext* context, const SkTDArray<GrHoistedLayer>& layers);

    /** Forceably remove all cached layers and release the atlas. Useful for debugging and timing.
        This is only functional when GR_CACHE_HOISTED_LAYERS is set to 1 in GrLayerCache.h
        @param context    Owner of the layer cache (and thus the layers)
     */
    static void PurgeCache(GrContext* context);

private:
    /** Update the GrTexture in 'layer' with its filtered version
        @param context    Owner of the layer cache (and thus the layers)
        @param device     Required by the filtering code
        @param info       Layer info for a layer needing filtering prior to being composited
     */
    static void FilterLayer(GrContext* context, SkGpuDevice* device, const GrHoistedLayer& info);

};

#endif
