1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#ifndef GrTexture_DEFINED
10#define GrTexture_DEFINED
11
12#include "GrSurface.h"
13#include "SkPoint.h"
14#include "GrRenderTarget.h"
15
16class GrResourceKey;
17class GrTextureParams;
18
19class GrTexture : public GrSurface {
20
21public:
22    SK_DECLARE_INST_COUNT(GrTexture)
23    // from GrResource
24    /**
25     * Informational texture flags
26     */
27    enum FlagBits {
28        kFirstBit = (kLastPublic_GrTextureFlagBit << 1),
29
30        /**
31         * This texture should be returned to the texture cache when
32         * it is no longer reffed
33         */
34        kReturnToCache_FlagBit        = kFirstBit,
35    };
36
37    void setFlag(GrTextureFlags flags) {
38        fDesc.fFlags = fDesc.fFlags | flags;
39    }
40    void resetFlag(GrTextureFlags flags) {
41        fDesc.fFlags = fDesc.fFlags & ~flags;
42    }
43    bool isSetFlag(GrTextureFlags flags) const {
44        return 0 != (fDesc.fFlags & flags);
45    }
46
47    void dirtyMipMaps(bool mipMapsDirty) {
48        fMipMapsDirty = mipMapsDirty;
49    }
50
51    bool mipMapsAreDirty() const {
52        return fMipMapsDirty;
53    }
54
55    /**
56     *  Approximate number of bytes used by the texture
57     */
58    virtual size_t sizeInBytes() const SK_OVERRIDE {
59        return (size_t) fDesc.fWidth *
60                        fDesc.fHeight *
61                        GrBytesPerPixel(fDesc.fConfig);
62    }
63
64    // GrSurface overrides
65    virtual bool readPixels(int left, int top, int width, int height,
66                            GrPixelConfig config,
67                            void* buffer,
68                            size_t rowBytes = 0,
69                            uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
70
71    virtual void writePixels(int left, int top, int width, int height,
72                             GrPixelConfig config,
73                             const void* buffer,
74                             size_t rowBytes = 0,
75                             uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
76
77    /**
78     * @return this texture
79     */
80    virtual GrTexture* asTexture() SK_OVERRIDE { return this; }
81    virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; }
82
83    /**
84     * Retrieves the render target underlying this texture that can be passed to
85     * GrGpu::setRenderTarget().
86     *
87     * @return    handle to render target or NULL if the texture is not a
88     *            render target
89     */
90    virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE {
91        return fRenderTarget.get();
92    }
93    virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE {
94        return fRenderTarget.get();
95    }
96
97    // GrTexture
98    /**
99     * Convert from texels to normalized texture coords for POT textures
100     * only.
101     */
102    GrFixed normalizeFixedX(GrFixed x) const {
103        SkASSERT(GrIsPow2(fDesc.fWidth));
104        return x >> fShiftFixedX;
105    }
106    GrFixed normalizeFixedY(GrFixed y) const {
107        SkASSERT(GrIsPow2(fDesc.fHeight));
108        return y >> fShiftFixedY;
109    }
110
111    /**
112     *  Return the native ID or handle to the texture, depending on the
113     *  platform. e.g. on OpenGL, return the texture ID.
114     */
115    virtual GrBackendObject getTextureHandle() const = 0;
116
117    /**
118     *  Call this when the state of the native API texture object is
119     *  altered directly, without being tracked by skia.
120     */
121    virtual void invalidateCachedState() = 0;
122
123#ifdef SK_DEBUG
124    void validate() const {
125        this->INHERITED::validate();
126
127        this->validateDesc();
128    }
129#endif
130
131    static GrResourceKey ComputeKey(const GrGpu* gpu,
132                                    const GrTextureParams* params,
133                                    const GrTextureDesc& desc,
134                                    const GrCacheID& cacheID);
135    static GrResourceKey ComputeScratchKey(const GrTextureDesc& desc);
136    static bool NeedsResizing(const GrResourceKey& key);
137    static bool NeedsBilerp(const GrResourceKey& key);
138
139protected:
140    // A texture refs its rt representation but not vice-versa. It is up to
141    // the subclass constructor to initialize this pointer.
142    SkAutoTUnref<GrRenderTarget> fRenderTarget;
143
144    GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
145    : INHERITED(gpu, isWrapped, desc)
146    , fRenderTarget(NULL)
147    , fMipMapsDirty(true) {
148
149        // only make sense if alloc size is pow2
150        fShiftFixedX = 31 - SkCLZ(fDesc.fWidth);
151        fShiftFixedY = 31 - SkCLZ(fDesc.fHeight);
152    }
153    virtual ~GrTexture();
154
155    // GrResource overrides
156    virtual void onRelease() SK_OVERRIDE;
157    virtual void onAbandon() SK_OVERRIDE;
158
159    void validateDesc() const;
160
161private:
162    // these two shift a fixed-point value into normalized coordinates
163    // for this texture if the texture is power of two sized.
164    int                 fShiftFixedX;
165    int                 fShiftFixedY;
166
167    bool                fMipMapsDirty;
168
169    virtual void internal_dispose() const SK_OVERRIDE;
170
171    typedef GrSurface INHERITED;
172};
173
174/**
175 * Represents a texture that is intended to be accessed in device coords with an offset.
176 */
177class GrDeviceCoordTexture {
178public:
179    GrDeviceCoordTexture() { fOffset.set(0, 0); }
180
181    GrDeviceCoordTexture(const GrDeviceCoordTexture& other) {
182        *this = other;
183    }
184
185    GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset)
186        : fTexture(SkSafeRef(texture))
187        , fOffset(offset) {
188    }
189
190    GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) {
191        fTexture.reset(SkSafeRef(other.fTexture.get()));
192        fOffset = other.fOffset;
193        return *this;
194    }
195
196    const SkIPoint& offset() const { return fOffset; }
197
198    void setOffset(const SkIPoint& offset) { fOffset = offset; }
199    void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
200
201    GrTexture* texture() const { return fTexture.get(); }
202
203    GrTexture* setTexture(GrTexture* texture) {
204        fTexture.reset(SkSafeRef(texture));
205        return texture;
206    }
207private:
208    SkAutoTUnref<GrTexture> fTexture;
209    SkIPoint                fOffset;
210};
211
212#endif
213