2015-04-30 21:18:54 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2015 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef GrTextureProvider_DEFINED
|
|
|
|
#define GrTextureProvider_DEFINED
|
|
|
|
|
|
|
|
#include "GrTexture.h"
|
2016-02-26 21:20:48 +00:00
|
|
|
#include "GrTypes.h"
|
2015-04-30 21:18:54 +00:00
|
|
|
|
2016-01-11 16:27:48 +00:00
|
|
|
class GrSingleOwner;
|
|
|
|
|
2015-04-30 21:18:54 +00:00
|
|
|
class SK_API GrTextureProvider {
|
|
|
|
public:
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Textures
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a new texture in the resource cache and returns it. The caller owns a
|
|
|
|
* ref on the returned texture which must be balanced by a call to unref.
|
|
|
|
*
|
2016-02-26 21:20:48 +00:00
|
|
|
* @param desc Description of the texture properties.
|
|
|
|
* @param budgeted Does the texture count against the resource cache budget?
|
|
|
|
* @param texels A contiguous array of mipmap levels
|
|
|
|
* @param mipLevelCount The amount of elements in the texels array
|
|
|
|
*/
|
|
|
|
GrTexture* createMipMappedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
|
|
|
|
const GrMipLevel* texels, int mipLevelCount);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This function is a shim which creates a SkTArray<GrMipLevel> of size 1.
|
|
|
|
* It then calls createTexture with that SkTArray.
|
|
|
|
*
|
2015-04-30 21:18:54 +00:00
|
|
|
* @param srcData Pointer to the pixel values (optional).
|
|
|
|
* @param rowBytes The number of bytes between rows of the texture. Zero
|
|
|
|
* implies tightly packed rows. For compressed pixel configs, this
|
|
|
|
* field is ignored.
|
|
|
|
*/
|
2016-02-25 16:33:02 +00:00
|
|
|
GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted, const void* srcData,
|
2015-04-30 21:18:54 +00:00
|
|
|
size_t rowBytes);
|
|
|
|
|
|
|
|
/** Shortcut for creating a texture with no initial data to upload. */
|
2016-02-25 16:33:02 +00:00
|
|
|
GrTexture* createTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted) {
|
2016-03-09 14:25:15 +00:00
|
|
|
return this->createTexture(desc, budgeted, nullptr, 0);
|
2015-04-30 21:18:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** Assigns a unique key to the texture. The texture will be findable via this key using
|
|
|
|
findTextureByUniqueKey(). If an existing texture has this key, it's key will be removed. */
|
|
|
|
void assignUniqueKeyToTexture(const GrUniqueKey& key, GrTexture* texture) {
|
|
|
|
this->assignUniqueKeyToResource(key, texture);
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Finds a texture by unique key. If the texture is found it is ref'ed and returned. */
|
2016-01-11 16:27:48 +00:00
|
|
|
GrTexture* findAndRefTextureByUniqueKey(const GrUniqueKey& key);
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines whether a texture is associated with the unique key. If the texture is found it
|
|
|
|
* will not be locked or returned. This call does not affect the priority of the resource for
|
|
|
|
* deletion.
|
|
|
|
*/
|
|
|
|
bool existsTextureWithUniqueKey(const GrUniqueKey& key) const {
|
|
|
|
return this->existsResourceWithUniqueKey(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-07-31 20:59:30 +00:00
|
|
|
* Finds a texture that approximately matches the descriptor. Will be at least as large in width
|
|
|
|
* and height as desc specifies. If desc specifies that the texture should be a render target
|
|
|
|
* then result will be a render target. Format and sample count will always match the request.
|
|
|
|
* The contents of the texture are undefined. The caller owns a ref on the returned texture and
|
|
|
|
* must balance with a call to unref.
|
2015-04-30 21:18:54 +00:00
|
|
|
*/
|
2015-07-31 20:59:30 +00:00
|
|
|
GrTexture* createApproxTexture(const GrSurfaceDesc&);
|
|
|
|
|
|
|
|
/** Legacy function that no longer should be used. */
|
2015-04-30 21:18:54 +00:00
|
|
|
enum ScratchTexMatch {
|
|
|
|
kExact_ScratchTexMatch,
|
|
|
|
kApprox_ScratchTexMatch
|
|
|
|
};
|
2015-07-31 20:59:30 +00:00
|
|
|
GrTexture* refScratchTexture(const GrSurfaceDesc& desc, ScratchTexMatch match) {
|
|
|
|
if (kApprox_ScratchTexMatch == match) {
|
|
|
|
return this->createApproxTexture(desc);
|
|
|
|
} else {
|
2016-02-25 16:33:02 +00:00
|
|
|
return this->createTexture(desc, SkBudgeted::kYes);
|
2015-07-31 20:59:30 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
// Wrapped Backend Surfaces
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Wraps an existing texture with a GrTexture object.
|
|
|
|
*
|
|
|
|
* OpenGL: if the object is a texture Gr may change its GL texture params
|
|
|
|
* when it is drawn.
|
|
|
|
*
|
|
|
|
* @return GrTexture object or NULL on failure.
|
|
|
|
*/
|
2016-10-27 16:30:08 +00:00
|
|
|
sk_sp<GrTexture> wrapBackendTexture(const GrBackendTextureDesc& desc,
|
|
|
|
GrWrapOwnership = kBorrow_GrWrapOwnership);
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Wraps an existing render target with a GrRenderTarget object. It is
|
|
|
|
* similar to wrapBackendTexture but can be used to draw into surfaces
|
|
|
|
* that are not also textures (e.g. FBO 0 in OpenGL, or an MSAA buffer that
|
2015-06-18 16:12:16 +00:00
|
|
|
* the client will resolve to a texture). Currently wrapped render targets
|
|
|
|
* always use the kBorrow_GrWrapOwnership semantics.
|
2015-04-30 21:18:54 +00:00
|
|
|
*
|
Add wrapBackendTextureAsRenderTarget API
Skia's GrTextureProvider currently exposes two APIs for wrapping backend
objects:
* wrapBackendTexture - wraps a texture into a GrTexture. Depending on
flags, this GrTexture can be converted to a GrRenderTarget. Skia
manages the render target objects it may create to provide a render
target for the texture. This allows Skia to create stencil buffers
if needed and manager MSAA resolves.
* wrapBackendRenderTarget - wraps a FBO into a GrRenderTarget. This
object cannot be converted to a GrTexture. Skia does not manage
the render target objects for such a GrRenderTarget, and as such
cannot attach stencil buffers or perform MSAA resolves on the
created GrRenderTarget.
Given these two options, wrapBackendTexture provides more versatility
and allows Skia more room for optimization. Chrome currently uses
wrapBackendTexture for this reason.
While these two functions cover most cases, they do not provide a way
for Skia to wrap a texture into a render target (and gain the MSAA and
stencil buffer management), without also creating a GrTexture. This is
problematic in cases where a texture can be bound to a render target,
but cannot be textured from, as is the case in Chrome's limited support
for GL_TEXTURE_RECTANGLE.
To address this, a new function is created:
* wrapBackendTextureAsRenderTarget - wraps a texture into a
GrRenderTarget. As with wrapBackendTexture, the created render
target objects are fully managed by Skia. Unlike wrapBackendTexture
no GrTexture is created, and the created object will never be
textured from.
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1709163003
Review URL: https://codereview.chromium.org/1709163003
2016-02-24 22:49:51 +00:00
|
|
|
* @return GrRenderTarget object or NULL on failure.
|
2015-04-30 21:18:54 +00:00
|
|
|
*/
|
2016-10-27 16:30:08 +00:00
|
|
|
sk_sp<GrRenderTarget> wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc);
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
protected:
|
2016-01-11 16:27:48 +00:00
|
|
|
GrTextureProvider(GrGpu* gpu, GrResourceCache* cache, GrSingleOwner* singleOwner);
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Assigns a unique key to a resource. If the key is associated with another resource that
|
|
|
|
* association is removed and replaced by this resource.
|
|
|
|
*/
|
|
|
|
void assignUniqueKeyToResource(const GrUniqueKey&, GrGpuResource*);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Finds a resource in the cache, based on the specified key. This is intended for use in
|
|
|
|
* conjunction with addResourceToCache(). The return value will be NULL if not found. The
|
|
|
|
* caller must balance with a call to unref().
|
|
|
|
*/
|
|
|
|
GrGpuResource* findAndRefResourceByUniqueKey(const GrUniqueKey&);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Determines whether a resource is in the cache. If the resource is found it
|
|
|
|
* will not be locked or returned. This call does not affect the priority of
|
|
|
|
* the resource for deletion.
|
|
|
|
*/
|
|
|
|
bool existsResourceWithUniqueKey(const GrUniqueKey& key) const;
|
|
|
|
|
2015-07-31 20:59:30 +00:00
|
|
|
enum ScratchTextureFlags {
|
|
|
|
kExact_ScratchTextureFlag = 0x1,
|
|
|
|
kNoPendingIO_ScratchTextureFlag = 0x2, // (http://skbug.com/4156)
|
|
|
|
kNoCreate_ScratchTextureFlag = 0x4,
|
|
|
|
};
|
|
|
|
|
|
|
|
/** A common impl for GrTextureProvider and GrResourceProvider variants. */
|
|
|
|
GrTexture* internalCreateApproxTexture(const GrSurfaceDesc& desc, uint32_t scratchTextureFlags);
|
|
|
|
|
|
|
|
GrTexture* refScratchTexture(const GrSurfaceDesc&, uint32_t scratchTextureFlags);
|
2015-04-30 21:18:54 +00:00
|
|
|
|
|
|
|
void abandon() {
|
|
|
|
fCache = NULL;
|
|
|
|
fGpu = NULL;
|
|
|
|
}
|
|
|
|
|
2015-05-04 17:36:42 +00:00
|
|
|
GrResourceCache* cache() { return fCache; }
|
|
|
|
const GrResourceCache* cache() const { return fCache; }
|
|
|
|
|
|
|
|
GrGpu* gpu() { return fGpu; }
|
|
|
|
const GrGpu* gpu() const { return fGpu; }
|
|
|
|
|
2015-04-30 21:18:54 +00:00
|
|
|
bool isAbandoned() const {
|
|
|
|
SkASSERT(SkToBool(fGpu) == SkToBool(fCache));
|
|
|
|
return !SkToBool(fCache);
|
|
|
|
}
|
|
|
|
|
2015-06-24 13:54:10 +00:00
|
|
|
private:
|
2015-04-30 21:18:54 +00:00
|
|
|
GrResourceCache* fCache;
|
|
|
|
GrGpu* fGpu;
|
2016-01-11 16:27:48 +00:00
|
|
|
|
|
|
|
// In debug builds we guard against improper thread handling
|
|
|
|
SkDEBUGCODE(mutable GrSingleOwner* fSingleOwner;)
|
2015-04-30 21:18:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|