michael@0: michael@0: /* michael@0: * Copyright 2011 Google Inc. michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: #ifndef GrTexture_DEFINED michael@0: #define GrTexture_DEFINED michael@0: michael@0: #include "GrSurface.h" michael@0: #include "SkPoint.h" michael@0: #include "GrRenderTarget.h" michael@0: michael@0: class GrResourceKey; michael@0: class GrTextureParams; michael@0: michael@0: class GrTexture : public GrSurface { michael@0: michael@0: public: michael@0: SK_DECLARE_INST_COUNT(GrTexture) michael@0: // from GrResource michael@0: /** michael@0: * Informational texture flags michael@0: */ michael@0: enum FlagBits { michael@0: kFirstBit = (kLastPublic_GrTextureFlagBit << 1), michael@0: michael@0: /** michael@0: * This texture should be returned to the texture cache when michael@0: * it is no longer reffed michael@0: */ michael@0: kReturnToCache_FlagBit = kFirstBit, michael@0: }; michael@0: michael@0: void setFlag(GrTextureFlags flags) { michael@0: fDesc.fFlags = fDesc.fFlags | flags; michael@0: } michael@0: void resetFlag(GrTextureFlags flags) { michael@0: fDesc.fFlags = fDesc.fFlags & ~flags; michael@0: } michael@0: bool isSetFlag(GrTextureFlags flags) const { michael@0: return 0 != (fDesc.fFlags & flags); michael@0: } michael@0: michael@0: void dirtyMipMaps(bool mipMapsDirty) { michael@0: fMipMapsDirty = mipMapsDirty; michael@0: } michael@0: michael@0: bool mipMapsAreDirty() const { michael@0: return fMipMapsDirty; michael@0: } michael@0: michael@0: /** michael@0: * Approximate number of bytes used by the texture michael@0: */ michael@0: virtual size_t sizeInBytes() const SK_OVERRIDE { michael@0: return (size_t) fDesc.fWidth * michael@0: fDesc.fHeight * michael@0: GrBytesPerPixel(fDesc.fConfig); michael@0: } michael@0: michael@0: // GrSurface overrides michael@0: virtual bool readPixels(int left, int top, int width, int height, michael@0: GrPixelConfig config, michael@0: void* buffer, michael@0: size_t rowBytes = 0, michael@0: uint32_t pixelOpsFlags = 0) SK_OVERRIDE; michael@0: michael@0: virtual void writePixels(int left, int top, int width, int height, michael@0: GrPixelConfig config, michael@0: const void* buffer, michael@0: size_t rowBytes = 0, michael@0: uint32_t pixelOpsFlags = 0) SK_OVERRIDE; michael@0: michael@0: /** michael@0: * @return this texture michael@0: */ michael@0: virtual GrTexture* asTexture() SK_OVERRIDE { return this; } michael@0: virtual const GrTexture* asTexture() const SK_OVERRIDE { return this; } michael@0: michael@0: /** michael@0: * Retrieves the render target underlying this texture that can be passed to michael@0: * GrGpu::setRenderTarget(). michael@0: * michael@0: * @return handle to render target or NULL if the texture is not a michael@0: * render target michael@0: */ michael@0: virtual GrRenderTarget* asRenderTarget() SK_OVERRIDE { michael@0: return fRenderTarget.get(); michael@0: } michael@0: virtual const GrRenderTarget* asRenderTarget() const SK_OVERRIDE { michael@0: return fRenderTarget.get(); michael@0: } michael@0: michael@0: // GrTexture michael@0: /** michael@0: * Convert from texels to normalized texture coords for POT textures michael@0: * only. michael@0: */ michael@0: GrFixed normalizeFixedX(GrFixed x) const { michael@0: SkASSERT(GrIsPow2(fDesc.fWidth)); michael@0: return x >> fShiftFixedX; michael@0: } michael@0: GrFixed normalizeFixedY(GrFixed y) const { michael@0: SkASSERT(GrIsPow2(fDesc.fHeight)); michael@0: return y >> fShiftFixedY; michael@0: } michael@0: michael@0: /** michael@0: * Return the native ID or handle to the texture, depending on the michael@0: * platform. e.g. on OpenGL, return the texture ID. michael@0: */ michael@0: virtual GrBackendObject getTextureHandle() const = 0; michael@0: michael@0: /** michael@0: * Call this when the state of the native API texture object is michael@0: * altered directly, without being tracked by skia. michael@0: */ michael@0: virtual void invalidateCachedState() = 0; michael@0: michael@0: #ifdef SK_DEBUG michael@0: void validate() const { michael@0: this->INHERITED::validate(); michael@0: michael@0: this->validateDesc(); michael@0: } michael@0: #endif michael@0: michael@0: static GrResourceKey ComputeKey(const GrGpu* gpu, michael@0: const GrTextureParams* params, michael@0: const GrTextureDesc& desc, michael@0: const GrCacheID& cacheID); michael@0: static GrResourceKey ComputeScratchKey(const GrTextureDesc& desc); michael@0: static bool NeedsResizing(const GrResourceKey& key); michael@0: static bool NeedsBilerp(const GrResourceKey& key); michael@0: michael@0: protected: michael@0: // A texture refs its rt representation but not vice-versa. It is up to michael@0: // the subclass constructor to initialize this pointer. michael@0: SkAutoTUnref fRenderTarget; michael@0: michael@0: GrTexture(GrGpu* gpu, bool isWrapped, const GrTextureDesc& desc) michael@0: : INHERITED(gpu, isWrapped, desc) michael@0: , fRenderTarget(NULL) michael@0: , fMipMapsDirty(true) { michael@0: michael@0: // only make sense if alloc size is pow2 michael@0: fShiftFixedX = 31 - SkCLZ(fDesc.fWidth); michael@0: fShiftFixedY = 31 - SkCLZ(fDesc.fHeight); michael@0: } michael@0: virtual ~GrTexture(); michael@0: michael@0: // GrResource overrides michael@0: virtual void onRelease() SK_OVERRIDE; michael@0: virtual void onAbandon() SK_OVERRIDE; michael@0: michael@0: void validateDesc() const; michael@0: michael@0: private: michael@0: // these two shift a fixed-point value into normalized coordinates michael@0: // for this texture if the texture is power of two sized. michael@0: int fShiftFixedX; michael@0: int fShiftFixedY; michael@0: michael@0: bool fMipMapsDirty; michael@0: michael@0: virtual void internal_dispose() const SK_OVERRIDE; michael@0: michael@0: typedef GrSurface INHERITED; michael@0: }; michael@0: michael@0: /** michael@0: * Represents a texture that is intended to be accessed in device coords with an offset. michael@0: */ michael@0: class GrDeviceCoordTexture { michael@0: public: michael@0: GrDeviceCoordTexture() { fOffset.set(0, 0); } michael@0: michael@0: GrDeviceCoordTexture(const GrDeviceCoordTexture& other) { michael@0: *this = other; michael@0: } michael@0: michael@0: GrDeviceCoordTexture(GrTexture* texture, const SkIPoint& offset) michael@0: : fTexture(SkSafeRef(texture)) michael@0: , fOffset(offset) { michael@0: } michael@0: michael@0: GrDeviceCoordTexture& operator=(const GrDeviceCoordTexture& other) { michael@0: fTexture.reset(SkSafeRef(other.fTexture.get())); michael@0: fOffset = other.fOffset; michael@0: return *this; michael@0: } michael@0: michael@0: const SkIPoint& offset() const { return fOffset; } michael@0: michael@0: void setOffset(const SkIPoint& offset) { fOffset = offset; } michael@0: void setOffset(int ox, int oy) { fOffset.set(ox, oy); } michael@0: michael@0: GrTexture* texture() const { return fTexture.get(); } michael@0: michael@0: GrTexture* setTexture(GrTexture* texture) { michael@0: fTexture.reset(SkSafeRef(texture)); michael@0: return texture; michael@0: } michael@0: private: michael@0: SkAutoTUnref fTexture; michael@0: SkIPoint fOffset; michael@0: }; michael@0: michael@0: #endif