/*
 * 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;
struct SkRect;

class GrHoistedLayer {
public:
    const SkPicture* fPicture;
    GrCachedLayer*   fLayer;
    SkIPoint         fOffset;
    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 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);
};

#endif
