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;
18class GrTextureImpl;
19
20class GrTexture : public GrSurface {
21public:
22    /**
23     *  Approximate number of bytes used by the texture
24     */
25    virtual size_t gpuMemorySize() const SK_OVERRIDE;
26
27    // GrSurface overrides
28    virtual bool readPixels(int left, int top, int width, int height,
29                            GrPixelConfig config,
30                            void* buffer,
31                            size_t rowBytes = 0,
32                            uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
33
34    virtual void writePixels(int left, int top, int width, int height,
35                             GrPixelConfig config,
36                             const void* buffer,
37                             size_t rowBytes = 0,
38                             uint32_t pixelOpsFlags = 0) SK_OVERRIDE;
39
40    virtual GrTexture* asTexture() SK_OVERRIDE { return this; }
41    virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; }
42    virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { return fRenderTarget.get(); }
43    virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { return fRenderTarget.get(); }
44
45    /**
46     * Convert from texels to normalized texture coords for POT textures only. Please don't add
47     * new callsites for these functions. They are slated for removal.
48     */
49    SkFixed normalizeFixedX(SkFixed x) const {
50        SkASSERT(SkIsPow2(fDesc.fWidth));
51        return x >> fShiftFixedX;
52    }
53    SkFixed normalizeFixedY(SkFixed y) const {
54        SkASSERT(SkIsPow2(fDesc.fHeight));
55        return y >> fShiftFixedY;
56    }
57
58    /**
59     *  Return the native ID or handle to the texture, depending on the
60     *  platform. e.g. on OpenGL, return the texture ID.
61     */
62    virtual GrBackendObject getTextureHandle() const = 0;
63
64    /**
65     * This function indicates that the texture parameters (wrap mode, filtering, ...) have been
66     * changed externally to Skia.
67     */
68    virtual void textureParamsModified() = 0;
69    SK_ATTR_DEPRECATED("Renamed to textureParamsModified.")
70    void invalidateCachedState() { this->textureParamsModified(); }
71
72    /**
73     * Informational texture flags. This will be moved to the private GrTextureImpl class soon.
74     */
75    enum FlagBits {
76        kFirstBit = (kLastPublic_GrTextureFlagBit << 1),
77
78        /**
79         * This texture should be returned to the texture cache when
80         * it is no longer reffed
81         */
82        kReturnToCache_FlagBit        = kFirstBit,
83    };
84
85    void resetFlag(GrTextureFlags flags) {
86        fDesc.fFlags = fDesc.fFlags & ~flags;
87    }
88
89#ifdef SK_DEBUG
90    void validate() const {
91        this->INHERITED::validate();
92
93        this->validateDesc();
94    }
95#endif
96
97    GrTextureImpl* impl() { return reinterpret_cast<GrTextureImpl*>(this); }
98    const GrTextureImpl* impl() const { return reinterpret_cast<const GrTextureImpl*>(this); }
99
100protected:
101    // A texture refs its rt representation but not vice-versa. It is up to
102    // the subclass constructor to initialize this pointer.
103    SkAutoTUnref<GrRenderTarget> fRenderTarget;
104
105    GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
106    : INHERITED(gpu, isWrapped, desc)
107    , fRenderTarget(NULL) {
108        // only make sense if alloc size is pow2
109        fShiftFixedX = 31 - SkCLZ(fDesc.fWidth);
110        fShiftFixedY = 31 - SkCLZ(fDesc.fHeight);
111    }
112
113    virtual ~GrTexture();
114
115    // GrResource overrides
116    virtual void onRelease() SK_OVERRIDE;
117    virtual void onAbandon() SK_OVERRIDE;
118
119    void validateDesc() const;
120
121private:
122    virtual void internal_dispose() const SK_OVERRIDE;
123
124    // these two shift a fixed-point value into normalized coordinates
125    // for this texture if the texture is power of two sized.
126    int                 fShiftFixedX;
127    int                 fShiftFixedY;
128
129    typedef GrSurface INHERITED;
130};
131
132class GrTextureImpl : public GrTexture {
133public:
134    SK_DECLARE_INST_COUNT(GrTextureImpl)
135
136    void setFlag(GrTextureFlags flags) {
137        fDesc.fFlags = fDesc.fFlags | flags;
138    }
139    void resetFlag(GrTextureFlags flags) {
140        fDesc.fFlags = fDesc.fFlags & ~flags;
141    }
142    bool isSetFlag(GrTextureFlags flags) const {
143        return 0 != (fDesc.fFlags & flags);
144    }
145
146    void dirtyMipMaps(bool mipMapsDirty);
147
148    bool mipMapsAreDirty() const {
149        return kValid_MipMapsStatus != fMipMapsStatus;
150    }
151
152    bool hasMipMaps() const {
153        return kNotAllocated_MipMapsStatus != fMipMapsStatus;
154    }
155
156    static GrResourceKey ComputeKey(const GrGpu* gpu,
157                                    const GrTextureParams* params,
158                                    const GrTextureDesc& desc,
159                                    const GrCacheID& cacheID);
160    static GrResourceKey ComputeScratchKey(const GrTextureDesc& desc);
161    static bool NeedsResizing(const GrResourceKey& key);
162    static bool NeedsBilerp(const GrResourceKey& key);
163
164protected:
165    GrTextureImpl(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc)
166    : INHERITED(gpu, isWrapped, desc)
167    , fMipMapsStatus(kNotAllocated_MipMapsStatus) {
168    }
169
170private:
171    enum MipMapsStatus {
172        kNotAllocated_MipMapsStatus,
173        kAllocated_MipMapsStatus,
174        kValid_MipMapsStatus
175    };
176
177    MipMapsStatus       fMipMapsStatus;
178
179    typedef GrTexture INHERITED;
180};
181
182/**
183 * Represents a texture that is intended to be accessed in device coords with an offset.
184 */
185class GrDeviceCoordTexture {
186public:
187    GrDeviceCoordTexture() { fOffset.set(0, 0); }
188
189    GrDeviceCoordTexture(const GrDeviceCoordTexture& other) {
190        *this = other;
191    }
192
193    GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset)
194        : fTexture(SkSafeRef(texture))
195        , fOffset(offset) {
196    }
197
198    GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) {
199        fTexture.reset(SkSafeRef(other.fTexture.get()));
200        fOffset = other.fOffset;
201        return *this;
202    }
203
204    const SkIPoint& offset() const { return fOffset; }
205
206    void setOffset(const SkIPoint& offset) { fOffset = offset; }
207    void setOffset(int ox, int oy) { fOffset.set(ox, oy); }
208
209    GrTexture* texture() const { return fTexture.get(); }
210
211    GrTexture* setTexture(GrTexture* texture) {
212        fTexture.reset(SkSafeRef(texture));
213        return texture;
214    }
215
216private:
217    SkAutoTUnref<GrTexture> fTexture;
218    SkIPoint                fOffset;
219};
220
221#endif
222