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

#ifndef GrTexture_DEFINED
#define GrTexture_DEFINED

#include "GrSurface.h"
#include "GrCacheID.h"

class GrRenderTarget;
class GrResourceKey;
class GrTextureParams;

/*
 * All uncached textures should have this value as their fClientCacheID
 */
static const uint64_t kUncached_CacheID = 0xAAAAAAAA;

/*
 * Scratch textures should all have this value as their fClientCacheID
 */
static const uint64_t kScratch_CacheID = 0xBBBBBBBB;


class GrTexture : public GrSurface {

public:
    SK_DECLARE_INST_COUNT(GrTexture)
    GR_DECLARE_RESOURCE_CACHE_TYPE()

    // from GrResource
    /**
     * Informational texture flags
     */
    enum FlagBits {
        kFirstBit = (kLastPublic_GrTextureFlagBit << 1),

        /**
         * This texture should be returned to the texture cache when
         * it is no longer reffed
         */
        kReturnToCache_FlagBit        = kFirstBit,
    };

    void setFlag(GrTextureFlags flags) {
        fDesc.fFlags = fDesc.fFlags | flags;
    }
    void resetFlag(GrTextureFlags flags) {
        fDesc.fFlags = fDesc.fFlags & ~flags;
    }
    bool isSetFlag(GrTextureFlags flags) const { 
        return 0 != (fDesc.fFlags & flags); 
    }

    /**
     *  Approximate number of bytes used by the texture
     */
    virtual size_t sizeInBytes() const SK_OVERRIDE {
        return (size_t) fDesc.fWidth * 
                        fDesc.fHeight * 
                        GrBytesPerPixel(fDesc.fConfig);
    }

    // from GrSurface
    /**
     * Read a rectangle of pixels from the texture.
     * @param left          left edge of the rectangle to read (inclusive)
     * @param top           top edge of the rectangle to read (inclusive)
     * @param width         width of rectangle to read in pixels.
     * @param height        height of rectangle to read in pixels.
     * @param config        the pixel config of the destination buffer
     * @param buffer        memory to read the rectangle into.
     * @param rowBytes      number of bytes bewtween consecutive rows. Zero
     *                      means rows are tightly packed.
     *
     * @return true if the read succeeded, false if not. The read can fail
     *              because of a unsupported pixel config.
     */
    virtual bool readPixels(int left, int top, int width, int height,
                            GrPixelConfig config, void* buffer,
                            size_t rowBytes) SK_OVERRIDE;

    /**
     * Writes a rectangle of pixels to the texture.
     * @param left          left edge of the rectangle to write (inclusive)
     * @param top           top edge of the rectangle to write (inclusive)
     * @param width         width of rectangle to write in pixels.
     * @param height        height of rectangle to write in pixels.
     * @param config        the pixel config of the source buffer
     * @param buffer        memory to read pixels from
     * @param rowBytes      number of bytes between consecutive rows. Zero
     *                      means rows are tightly packed.
     */
    virtual void writePixels(int left, int top, int width, int height,
                             GrPixelConfig config, const void* buffer,
                             size_t rowBytes) SK_OVERRIDE;

    /**
     * @return this texture
     */
    virtual GrTexture* asTexture() SK_OVERRIDE { return this; }
    virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; }

    /**
     * Retrieves the render target underlying this texture that can be passed to
     * GrGpu::setRenderTarget().
     *
     * @return    handle to render target or NULL if the texture is not a
     *            render target
     */
    virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { 
        return fRenderTarget; 
    }
    virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { 
        return fRenderTarget; 
    }

    // GrTexture
    /**
     * Convert from texels to normalized texture coords for POT textures
     * only.
     */
    GrFixed normalizeFixedX(GrFixed x) const { 
        GrAssert(GrIsPow2(fDesc.fWidth));
        return x >> fShiftFixedX; 
    }
    GrFixed normalizeFixedY(GrFixed y) const { 
        GrAssert(GrIsPow2(fDesc.fHeight));
        return y >> fShiftFixedY; 
    }

    /**
     * Removes the reference on the associated GrRenderTarget held by this
     * texture. Afterwards asRenderTarget() will return NULL. The
     * GrRenderTarget survives the release if another ref is held on it.
     */
    void releaseRenderTarget();

    /**
     *  Return the native ID or handle to the texture, depending on the
     *  platform. e.g. on opengl, return the texture ID.
     */
    virtual intptr_t getTextureHandle() const = 0;

    /**
     *  Call this when the state of the native API texture object is
     *  altered directly, without being tracked by skia. 
     */
    virtual void invalidateCachedState() = 0;

#if GR_DEBUG
    void validate() const {
        this->INHERITED::validate();

        this->validateDesc();
    }
#else
    void validate() const {}
#endif

    static GrResourceKey ComputeKey(const GrGpu* gpu,
                                    const GrTextureParams* sampler,
                                    const GrTextureDesc& desc,
                                    bool scratch);

    static bool NeedsResizing(const GrResourceKey& key);
    static bool IsScratchTexture(const GrResourceKey& key);
    static bool NeedsFiltering(const GrResourceKey& key);

protected:
    GrRenderTarget* fRenderTarget; // texture refs its rt representation
                                   // base class cons sets to NULL
                                   // subclass cons can create and set

    GrTexture(GrGpu* gpu, const GrTextureDesc& desc)
    : INHERITED(gpu, desc)
    , fRenderTarget(NULL) {

        // only make sense if alloc size is pow2
        fShiftFixedX = 31 - Gr_clz(fDesc.fWidth);
        fShiftFixedY = 31 - Gr_clz(fDesc.fHeight);
    }

    // GrResource overrides
    virtual void onRelease() SK_OVERRIDE;
    virtual void onAbandon() SK_OVERRIDE;

    void validateDesc() const;

private:
    // these two shift a fixed-point value into normalized coordinates
    // for this texture if the texture is power of two sized.
    int                 fShiftFixedX;
    int                 fShiftFixedY;

    virtual void internal_dispose() const SK_OVERRIDE;

    typedef GrSurface INHERITED;
};

#endif

