/**
* Return a new surface whose contents will be drawn to an offscreen
* render target, allocated by the surface.
- *
- * The GrTextureStorageAllocator will be reused if SkImage snapshots create
- * additional textures.
*/
static sk_sp<SkSurface> MakeRenderTarget(
- GrContext*, SkBudgeted, const SkImageInfo&, int sampleCount, const SkSurfaceProps*,
- GrTextureStorageAllocator = GrTextureStorageAllocator());
+ GrContext*, SkBudgeted, const SkImageInfo&, int sampleCount, const SkSurfaceProps*);
static sk_sp<SkSurface> MakeRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) {
return MakeRenderTarget(gr, b, info, 0, nullptr);
return MakeFromBackendTextureAsRenderTarget(ctx, desc, props).release();
}
static SkSurface* NewRenderTarget(GrContext* ctx, SkBudgeted b, const SkImageInfo& info,
- int sampleCount, const SkSurfaceProps* props = NULL,
- GrTextureStorageAllocator a = GrTextureStorageAllocator()) {
+ int sampleCount, const SkSurfaceProps* props = NULL) {
return MakeRenderTarget(ctx, b, info, sampleCount, props, a).release();
}
static SkSurface* NewRenderTarget(GrContext* gr, SkBudgeted b, const SkImageInfo& info) {
};
/**
- * An container of function pointers which consumers of Skia can fill in and
- * pass to Skia. Skia will use these function pointers in place of its backend
- * API texture creation function. Either all of the function pointers should be
- * filled in, or they should all be nullptr.
- */
-struct GrTextureStorageAllocator {
- GrTextureStorageAllocator()
- : fAllocateTextureStorage(nullptr)
- , fDeallocateTextureStorage(nullptr) {
- }
-
- enum class Result {
- kSucceededAndUploaded,
- kSucceededWithoutUpload,
- kFailed
- };
- typedef Result (*AllocateTextureStorageProc)(
- void* ctx, GrBackendObject texture, unsigned width,
- unsigned height, GrPixelConfig config, const void* srcData, GrSurfaceOrigin);
- typedef void (*DeallocateTextureStorageProc)(void* ctx, GrBackendObject texture);
-
- /*
- * Generates and binds a texture to |textureStorageTarget()|. Allocates
- * storage for the texture.
- *
- * In OpenGL, the MIN and MAX filters for the created texture must be
- * GL_LINEAR. The WRAP_S and WRAP_T must be GL_CLAMP_TO_EDGE.
- *
- * If |srcData| is not nullptr, then the implementation of this function
- * may attempt to upload the data into the texture. On successful upload,
- * or if |srcData| is nullptr, returns kSucceededAndUploaded.
- */
- AllocateTextureStorageProc fAllocateTextureStorage;
-
- /*
- * Deallocate the storage for the given texture.
- *
- * Skia does not always destroy its outstanding textures. See
- * GrContext::abandonContext() for more details. The consumer of Skia is
- * responsible for making sure that all textures are destroyed, even if this
- * callback is not invoked.
- */
- DeallocateTextureStorageProc fDeallocateTextureStorage;
-
- /*
- * The context to use when invoking fAllocateTextureStorage and
- * fDeallocateTextureStorage.
- */
- void* fCtx;
-};
-
-/**
* Describes a surface to be created.
*/
struct GrSurfaceDesc {
* max supported count.
*/
int fSampleCnt;
-
- /**
- * A custom platform-specific allocator to use in place of the backend APIs
- * usual texture creation method (e.g. TexImage2D in OpenGL).
- */
- GrTextureStorageAllocator fTextureStorageAllocator;
-
bool fIsMipMapped; //!< Indicates if the texture has mipmaps
};
GrSLType samplerType, bool wasMipMapDataProvided)
: INHERITED(gpu, lifeCycle, desc)
, fSamplerType(samplerType) {
- if (!this->isExternal() && !GrPixelConfigIsCompressed(desc.fConfig) &&
- !desc.fTextureStorageAllocator.fAllocateTextureStorage) {
+ if (!this->isExternal() && !GrPixelConfigIsCompressed(desc.fConfig)) {
GrScratchKey key;
GrTexturePriv::ComputeScratchKey(desc, &key);
this->setScratchKey(key);
!fGpu->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
return nullptr;
}
- if (!GrPixelConfigIsCompressed(desc.fConfig) &&
- !desc.fTextureStorageAllocator.fAllocateTextureStorage) {
+ if (!GrPixelConfigIsCompressed(desc.fConfig)) {
if (mipLevelCount < 2) {
static const uint32_t kFlags = kExact_ScratchTextureFlag |
kNoCreate_ScratchTextureFlag;
SkGpuDevice* SkGpuDevice::Create(GrContext* context, SkBudgeted budgeted,
const SkImageInfo& info, int sampleCount,
- const SkSurfaceProps* props, InitContents init,
- GrTextureStorageAllocator customAllocator) {
+ const SkSurfaceProps* props, InitContents init) {
unsigned flags;
if (!CheckAlphaTypeAndGetFlags(&info, init, &flags)) {
return nullptr;
}
- SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(
- context, budgeted, info, sampleCount, customAllocator));
+ SkAutoTUnref<GrRenderTarget> rt(CreateRenderTarget(context, budgeted, info, sampleCount));
if (nullptr == rt) {
return nullptr;
}
}
}
-GrRenderTarget* SkGpuDevice::CreateRenderTarget(
- GrContext* context, SkBudgeted budgeted, const SkImageInfo& origInfo,
- int sampleCount, GrTextureStorageAllocator textureStorageAllocator) {
+GrRenderTarget* SkGpuDevice::CreateRenderTarget(GrContext* context, SkBudgeted budgeted,
+ const SkImageInfo& origInfo, int sampleCount) {
if (kUnknown_SkColorType == origInfo.colorType() ||
origInfo.width() < 0 || origInfo.height() < 0) {
return nullptr;
desc.fHeight = info.height();
desc.fConfig = SkImageInfo2GrPixelConfig(info, *context->caps());
desc.fSampleCnt = sampleCount;
- desc.fTextureStorageAllocator = textureStorageAllocator;
desc.fIsMipMapped = false;
GrTexture* texture = context->textureProvider()->createTexture(desc, budgeted, nullptr, 0);
if (nullptr == texture) {
SkBudgeted budgeted = fRenderTarget->resourcePriv().isBudgeted();
SkAutoTUnref<GrRenderTarget> newRT(CreateRenderTarget(
- this->context(), budgeted, this->imageInfo(), fRenderTarget->desc().fSampleCnt,
- fRenderTarget->desc().fTextureStorageAllocator));
+ this->context(), budgeted, this->imageInfo(), fRenderTarget->desc().fSampleCnt));
if (nullptr == newRT) {
return;
* the resource cache budget. On failure, returns nullptr.
*/
static SkGpuDevice* Create(GrContext*, SkBudgeted, const SkImageInfo&,
- int sampleCount, const SkSurfaceProps*,
- InitContents, GrTextureStorageAllocator = GrTextureStorageAllocator());
+ int sampleCount, const SkSurfaceProps*, InitContents);
~SkGpuDevice() override {}
bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);
static GrRenderTarget* CreateRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&,
- int sampleCount, GrTextureStorageAllocator);
+ int sampleCount);
void drawSpriteWithFilter(const SkDraw&, const SkBitmap&, int x, int y,
const SkPaint&) override;
}
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fConfig = SkImageInfo2GrPixelConfig(dstCT, kPremul_SkAlphaType, dstPT, *context->caps());
- desc.fTextureStorageAllocator = texture->desc().fTextureStorageAllocator;
desc.fIsMipMapped = false;
GrTexture* dst = context->textureProvider()->createTexture(desc, SkBudgeted::kNo, nullptr, 0);
bool succeeded = true;
if (kNewTexture_UploadType == uploadType &&
0 == left && 0 == top &&
- desc.fWidth == width && desc.fHeight == height &&
- !desc.fTextureStorageAllocator.fAllocateTextureStorage) {
+ desc.fWidth == width && desc.fHeight == height) {
succeeded = allocate_and_populate_uncompressed_texture(desc, *interface, caps, target,
internalFormat, externalFormat,
externalType, texelsShallowCopy,
bool GrGLGpu::createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
const SkTArray<GrMipLevel>& texels) {
- if (desc.fTextureStorageAllocator.fAllocateTextureStorage) {
- return this->createTextureExternalAllocatorImpl(desc, info, texels);
- }
-
info->fID = 0;
info->fTarget = GR_GL_TEXTURE_2D;
GL_CALL(GenTextures(1, &(info->fID)));
return true;
}
-bool GrGLGpu::createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc,
- GrGLTextureInfo* info,
- const SkTArray<GrMipLevel>& texels) {
- // We do not make SkTArray available outside of Skia,
- // and so we do not want to allow mipmaps to external
- // allocators just yet.
- SkASSERT(texels.count() < 2);
-
- const void* pixels = nullptr;
- if (!texels.empty()) {
- pixels = texels.begin()->fPixels;
- }
- switch (desc.fTextureStorageAllocator.fAllocateTextureStorage(
- desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendObject>(info),
- desc.fWidth, desc.fHeight, desc.fConfig, pixels, desc.fOrigin)) {
- case GrTextureStorageAllocator::Result::kSucceededAndUploaded:
- return true;
- case GrTextureStorageAllocator::Result::kFailed:
- return false;
- case GrTextureStorageAllocator::Result::kSucceededWithoutUpload:
- break;
- }
-
- if (!this->uploadTexData(desc, info->fTarget, kNewTexture_UploadType, 0, 0,
- desc.fWidth, desc.fHeight,
- desc.fConfig, texels)) {
- desc.fTextureStorageAllocator.fDeallocateTextureStorage(
- desc.fTextureStorageAllocator.fCtx, reinterpret_cast<GrBackendObject>(info));
- return false;
- }
- return true;
-}
-
GrStencilAttachment* GrGLGpu::createStencilAttachmentForRenderTarget(const GrRenderTarget* rt,
int width,
int height) {
// compatible stencil format, or negative if there is no compatible stencil format.
int getCompatibleStencilIndex(GrPixelConfig config);
- // If |desc.fTextureStorageAllocator| exists, use that to create the
- // texture. Otherwise, create the texture directly.
+
// Returns whether the texture is successfully created. On success, the
// result is stored in |info|.
// The texture is populated with |texels|, if it exists.
bool createTextureImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
bool renderTarget, GrGLTexture::TexParams* initialTexParams,
const SkTArray<GrMipLevel>& texels);
- bool createTextureExternalAllocatorImpl(const GrSurfaceDesc& desc, GrGLTextureInfo* info,
- const SkTArray<GrMipLevel>& texels);
void onClear(GrRenderTarget*, const SkIRect& rect, GrColor color) override;
void GrGLTexture::onRelease() {
if (fInfo.fID) {
if (GrGpuResource::kBorrowed_LifeCycle != fTextureIDLifecycle) {
- if (this->desc().fTextureStorageAllocator.fDeallocateTextureStorage) {
- this->desc().fTextureStorageAllocator.fDeallocateTextureStorage(
- this->desc().fTextureStorageAllocator.fCtx,
- reinterpret_cast<GrBackendObject>(&fInfo));
- } else {
- GL_CALL(DeleteTextures(1, &fInfo.fID));
- }
+ GL_CALL(DeleteTextures(1, &fInfo.fID));
}
fInfo.fID = 0;
}
}
sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext*, SkBudgeted, const SkImageInfo&, int,
- const SkSurfaceProps*, GrTextureStorageAllocator) {
+ const SkSurfaceProps*) {
return nullptr;
}
sk_sp<SkSurface> SkSurface::MakeRenderTarget(GrContext* ctx, SkBudgeted budgeted,
const SkImageInfo& info, int sampleCount,
- const SkSurfaceProps* props,
- GrTextureStorageAllocator customAllocator) {
+ const SkSurfaceProps* props) {
SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(
- ctx, budgeted, info, sampleCount, props, SkGpuDevice::kClear_InitContents,
- customAllocator));
+ ctx, budgeted, info, sampleCount, props, SkGpuDevice::kClear_InitContents));
if (!device) {
return nullptr;
}
+++ /dev/null
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "Test.h"
-#if SK_SUPPORT_GPU
-#include "gl/GrGLGpu.h"
-#include "gl/GLTestContext.h"
-#include "GrContext.h"
-#include "SkSurface_Gpu.h"
-#include "../include/gpu/GrTypes.h"
-#include "../include/private/SkTemplates.h"
-
-class TestStorageAllocator {
- public:
- static GrTextureStorageAllocator::Result allocateTextureStorage(void* ctx,
- GrBackendObject texture, unsigned width, unsigned height, GrPixelConfig config,
- const void* srcData, GrSurfaceOrigin) {
- TestStorageAllocator* allocator = static_cast<TestStorageAllocator*>(ctx);
- if (!allocator->m_allowAllocation)
- return GrTextureStorageAllocator::Result::kFailed;
- SkAutoTMalloc<uint8_t> pixels(width * height * 4);
- memset(pixels.get(), 0, width * height * 4);
-
- GrGLuint id;
- GrGLenum target = GR_GL_TEXTURE_2D;
- GR_GL_CALL(allocator->m_gl, GenTextures(1, &id));
- GR_GL_CALL(allocator->m_gl, BindTexture(target, id));
- GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_MAG_FILTER, GR_GL_NEAREST));
- GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_MIN_FILTER, GR_GL_NEAREST));
- GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_WRAP_S, GR_GL_CLAMP_TO_EDGE));
- GR_GL_CALL(allocator->m_gl, TexParameteri(target, GR_GL_TEXTURE_WRAP_T, GR_GL_CLAMP_TO_EDGE));
- GR_GL_CALL(allocator->m_gl, TexImage2D(target, 0, GR_GL_RGBA, width, height, 0, GR_GL_RGBA,
- GR_GL_UNSIGNED_BYTE, pixels.get()));
-
- GrGLTextureInfo* info = reinterpret_cast<GrGLTextureInfo*>(texture);
- info->fID = id;
- info->fTarget = target;
- allocator->m_mostRecentlyAllocatedStorage = id;
- return GrTextureStorageAllocator::Result::kSucceededWithoutUpload;
- }
- static void deallocateTextureStorage(void* ctx, GrBackendObject texture) {
- TestStorageAllocator* allocator = static_cast<TestStorageAllocator*>(ctx);
- GrGLTextureInfo* info = reinterpret_cast<GrGLTextureInfo*>(texture);
- GR_GL_CALL(allocator->m_gl, DeleteTextures(1, &(info->fID)));
- }
-
- GrGLuint m_mostRecentlyAllocatedStorage;
- const GrGLInterface* m_gl;
- bool m_allowAllocation;
-};
-
-DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CustomTexture, reporter, ctxInfo) {
- GrContext* context = ctxInfo.fGrContext;
- sk_gpu_test::GLTestContext* glContext = ctxInfo.fGLContext;
- static const int kWidth = 13;
- static const int kHeight = 13;
-
- const GrGLInterface* gl = glContext->gl();
- TestStorageAllocator allocator;
- allocator.m_allowAllocation = true;
- allocator.m_gl = gl;
- GrTextureStorageAllocator grAllocator;
- grAllocator.fAllocateTextureStorage = &TestStorageAllocator::allocateTextureStorage;
- grAllocator.fDeallocateTextureStorage= &TestStorageAllocator::deallocateTextureStorage;
- grAllocator.fCtx = &allocator;
-
- auto surface(SkSurface_Gpu::MakeRenderTarget(
- context, SkBudgeted::kNo, SkImageInfo::MakeN32Premul(kWidth, kHeight), 0,
- NULL, grAllocator));
- REPORTER_ASSERT(reporter, surface);
- GrGLuint id = allocator.m_mostRecentlyAllocatedStorage;
-
- sk_sp<SkImage> image(surface->makeImageSnapshot());
- REPORTER_ASSERT(reporter, image->isTextureBacked());
- SkImageInfo imageInfo = SkImageInfo::MakeN32Premul(1,1);
- GrColor dest = 0x11223344;
- REPORTER_ASSERT(reporter, image->readPixels(imageInfo, &dest, 4 * kWidth, 0, 0));
- REPORTER_ASSERT(reporter, GrColorUnpackG(dest) == 0);
-
- surface->getCanvas()->clear(SK_ColorGREEN);
- sk_sp<SkImage> image2(surface->makeImageSnapshot());
- REPORTER_ASSERT(reporter, image2->isTextureBacked());
- REPORTER_ASSERT(reporter, allocator.m_mostRecentlyAllocatedStorage != id);
-
- REPORTER_ASSERT(reporter, image2->readPixels(imageInfo, &dest, 4 * kWidth, 0, 0));
- REPORTER_ASSERT(reporter, GrColorUnpackG(dest) == 255);
-}
-
-DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(CustomTextureFailure, reporter, ctxInfo) {
- static const int kWidth = 13;
- static const int kHeight = 13;
-
- const GrGLInterface* gl = ctxInfo.fGLContext->gl();
- TestStorageAllocator allocator;
- allocator.m_allowAllocation = false;
- allocator.m_gl = gl;
- GrTextureStorageAllocator grAllocator;
- grAllocator.fAllocateTextureStorage = &TestStorageAllocator::allocateTextureStorage;
- grAllocator.fDeallocateTextureStorage= &TestStorageAllocator::deallocateTextureStorage;
- grAllocator.fCtx = &allocator;
- auto surface(SkSurface_Gpu::MakeRenderTarget(
- ctxInfo.fGrContext, SkBudgeted::kNo, SkImageInfo::MakeN32Premul(kWidth, kHeight), 0,
- NULL, grAllocator));
- REPORTER_ASSERT(reporter, !surface);
-}
-
-#endif