180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
2363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Copyright 2011 Google Inc.
3363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger *
4363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * Use of this source code is governed by a BSD-style license that can be
5363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#ifndef GrRenderTarget_DEFINED
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GrRenderTarget_DEFINED
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrSurface.h"
1258190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger#include "SkRect.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrStencilBuffer;
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrTexture;
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/**
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * A context's render target is set by setRenderTarget(). Render targets are
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * created by a createTexture with the kRenderTarget_TextureFlag flag.
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Additionally, GrContext provides methods for creating GrRenderTargets
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * that wrap externally created render targets.
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruclass GrRenderTarget : public GrSurface {
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querupublic:
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SK_DECLARE_INST_COUNT(GrRenderTarget)
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // GrResource overrides
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual size_t sizeInBytes() const SK_OVERRIDE;
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // GrSurface overrides
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
33363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * @return the texture associated with the render target, may be NULL.
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual GrTexture* asTexture() SK_OVERRIDE { return fTexture; }
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual const GrTexture* asTexture() const SK_OVERRIDE { return fTexture; }
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return this render target.
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return this; }
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual const GrRenderTarget* asRenderTarget() const  SK_OVERRIDE {
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return this;
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual bool readPixels(int left, int top, int width, int height,
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            GrPixelConfig config,
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            void* buffer,
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            size_t rowBytes = 0,
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                            uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void writePixels(int left, int top, int width, int height,
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             GrPixelConfig config,
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             const void* buffer,
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             size_t rowBytes = 0,
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                             uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // GrRenderTarget
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * If this RT is multisampled, this is the multisample buffer
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
63363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual GrBackendObject getRenderTargetHandle() const = 0;
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * If this RT is multisampled, this is the buffer it is resolved to.
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Otherwise, same as getRenderTargetHandle().
68363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * (In GL a separate FBO ID is used for the MSAA and resolved buffers)
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return the 3D API's handle to this object (e.g. FBO ID in OpenGL)
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
71363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    virtual GrBackendObject getRenderTargetResolvedHandle() const = 0;
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return true if the surface is multisampled, false otherwise
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool isMultisampled() const { return 0 != fDesc.fSampleCnt; }
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return the number of samples-per-pixel or zero if non-MSAA.
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    int numSamples() const { return fDesc.fSampleCnt; }
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Call to indicate the multisample contents were modified such that the
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * render target needs to be resolved before it can be used as texture. Gr
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * tracks this for its own drawing and thus this only needs to be called
87363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * when the render target has been modified outside of Gr. This has no
88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     * effect on wrapped backend render targets.
89363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger     *
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @param rect  a rect bounding the area needing resolve. NULL indicates
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     *              the whole RT needs resolving.
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
9358190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void flagAsNeedingResolve(const SkIRect* rect = NULL);
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Call to override the region that needs to be resolved.
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
9858190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    void overrideResolveRect(const SkIRect rect);
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Call to indicate that GrRenderTarget was externally resolved. This may
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * allow Gr to skip a redundant resolve step.
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void flagAsResolved() { fResolveRect.setLargestInverted(); }
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * @return true if the GrRenderTarget requires MSAA resolving
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool needsResolve() const { return !fResolveRect.isEmpty(); }
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * Returns a rect bounding the region needing resolving.
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
11458190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    const SkIRect& getResolveRect() const { return fResolveRect; }
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * If the render target is multisampled this will perform a multisample
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * resolve. Any pending draws to the target are first flushed. This only
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * applies to render targets that are associated with GrTextures. After the
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * function returns the GrTexture will contain the resolved pixels.
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void resolve();
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // a MSAA RT may require explicit resolving , it may auto-resolve (e.g. FBO
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // 0 in GL), or be unresolvable because the client didn't give us the
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // resolve destination.
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    enum ResolveType {
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kCanResolve_ResolveType,
12980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kAutoResolves_ResolveType,
13080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        kCantResolve_ResolveType,
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    };
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual ResolveType getResolveType() const = 0;
13380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
13480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    /**
13580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     * GrStencilBuffer is not part of the public API.
13680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru     */
13780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrStencilBuffer* getStencilBuffer() const { return fStencilBuffer; }
13880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    void setStencilBuffer(GrStencilBuffer* stencilBuffer);
13980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
14080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprotected:
14180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrRenderTarget(GrGpu* gpu,
142d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                   bool isWrapped,
14380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                   GrTexture* texture,
144096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                   const GrTextureDesc& desc)
145096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        : INHERITED(gpu, isWrapped, desc)
14680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        , fStencilBuffer(NULL)
14780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        , fTexture(texture) {
14880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fResolveRect.setLargestInverted();
14980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // override of GrResource
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onAbandon() SK_OVERRIDE;
15380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    virtual void onRelease() SK_OVERRIDE;
15480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
15580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruprivate:
1567839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    friend class GrTexture;
1577839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    // called by ~GrTexture to remove the non-ref'ed back ptr.
1587839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    void owningTextureDestroyed() {
1597839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrAssert(NULL != fTexture);
1607839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fTexture = NULL;
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger    }
1627839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrStencilBuffer*  fStencilBuffer;
16480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrTexture*        fTexture; // not ref'ed
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16658190644c30e1c4aa8e527f3503c58f841e0fcf3Derek Sollenberger    SkIRect           fResolveRect;
16780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    typedef GrSurface INHERITED;
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru};
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
172