Switch GrTextureStripAtlas over to GrTextureProxies

This is split out of: https://skia-review.googlesource.com/c/8823/ (Remove GrFragmentProcessor-derived class' GrTexture-based ctors)

Change-Id: I9f602985b6010fc58b595e2be6d4e67e50179747
Reviewed-on: https://skia-review.googlesource.com/8881
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Robert Phillips 2017-02-22 15:28:38 -05:00 committed by Skia Commit-Bot
parent bcfb8f639e
commit 30f9bc69cf
13 changed files with 162 additions and 94 deletions

View File

@ -205,23 +205,26 @@ public:
TextureSampler(); TextureSampler();
TextureSampler(GrTexture*, const GrSamplerParams&); TextureSampler(GrTexture*, const GrSamplerParams&);
explicit TextureSampler(GrTexture*, explicit TextureSampler(GrTexture*,
GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode, GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode, SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
GrShaderFlags visibility = kFragment_GrShaderFlag); GrShaderFlags visibility = kFragment_GrShaderFlag);
void reset(GrTexture*, const GrSamplerParams&,
TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&); GrShaderFlags visibility = kFragment_GrShaderFlag);
void reset(GrTexture*,
GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
GrShaderFlags visibility = kFragment_GrShaderFlag);
// MDB TODO: ultimately we shouldn't need the texProvider parameter // MDB TODO: ultimately we shouldn't need the texProvider parameter
TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&);
explicit TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>, explicit TextureSampler(GrTextureProvider*, sk_sp<GrTextureProxy>,
GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode, GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode, SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
GrShaderFlags visibility = kFragment_GrShaderFlag); GrShaderFlags visibility = kFragment_GrShaderFlag);
void reset(GrTextureProvider*, sk_sp<GrTextureProxy>, const GrSamplerParams&,
void reset(GrTexture*, const GrSamplerParams&,
GrShaderFlags visibility = kFragment_GrShaderFlag); GrShaderFlags visibility = kFragment_GrShaderFlag);
void reset(GrTexture*, void reset(GrTextureProvider*, sk_sp<GrTextureProxy>,
GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode, GrSamplerParams::FilterMode = GrSamplerParams::kNone_FilterMode,
SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode, SkShader::TileMode tileXAndY = SkShader::kClamp_TileMode,
GrShaderFlags visibility = kFragment_GrShaderFlag); GrShaderFlags visibility = kFragment_GrShaderFlag);

View File

@ -433,7 +433,8 @@ private:
friend class GrStencilAndCoverPathRenderer; // for access to addDrawOp friend class GrStencilAndCoverPathRenderer; // for access to addDrawOp
friend class GrTessellatingPathRenderer; // for access to addDrawOp friend class GrTessellatingPathRenderer; // for access to addDrawOp
// for a unit test // for a unit test
friend void test_draw_op(GrRenderTargetContext*, sk_sp<GrFragmentProcessor>, GrTexture*); friend void test_draw_op(GrContext*, GrRenderTargetContext*,
sk_sp<GrFragmentProcessor>, sk_sp<GrTextureProxy>);
void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip); void internalClear(const GrFixedClip&, const GrColor, bool canIgnoreClip);
@ -469,7 +470,7 @@ private:
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
size_t dstRowBytes, int x, int y) override; size_t dstRowBytes, int x, int y) override;
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y) override; size_t srcRowBytes, int x, int y, uint32_t flags) override;
// This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList. // This entry point allows the GrTextContext-derived classes to add their ops to the GrOpList.
void addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>); void addDrawOp(const GrPipelineBuilder&, const GrClip&, std::unique_ptr<GrDrawOp>);

View File

@ -91,8 +91,8 @@ public:
* unsupported pixel config. * unsupported pixel config.
*/ */
bool writePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes, bool writePixels(const SkImageInfo& srcInfo, const void* srcBuffer, size_t srcRowBytes,
int x, int y) { int x, int y, uint32_t flags = 0) {
return this->onWritePixels(srcInfo, srcBuffer, srcRowBytes, x, y); return this->onWritePixels(srcInfo, srcBuffer, srcRowBytes, x, y, flags);
} }
// TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy? // TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy?
@ -139,7 +139,7 @@ private:
virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
size_t dstRowBytes, int x, int y) = 0; size_t dstRowBytes, int x, int y) = 0;
virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y) = 0; size_t srcRowBytes, int x, int y, uint32_t flags) = 0;
GrDrawingManager* fDrawingManager; GrDrawingManager* fDrawingManager;

View File

@ -50,7 +50,7 @@ private:
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer, bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
size_t dstRowBytes, int x, int y) override; size_t dstRowBytes, int x, int y) override;
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y) override; size_t srcRowBytes, int x, int y, uint32_t flags) override;
GrTextureOpList* getOpList(); GrTextureOpList* getOpList();

View File

@ -15,6 +15,9 @@
#include "SkTDynamicHash.h" #include "SkTDynamicHash.h"
#include "SkTypes.h" #include "SkTypes.h"
class GrSurfaceContext;
class GrTextureProxy;
/** /**
* Maintains a single large texture whose rows store many textures of a small fixed height, * Maintains a single large texture whose rows store many textures of a small fixed height,
* stored in rows across the x-axis such that we can safely wrap/repeat them horizontally. * stored in rows across the x-axis such that we can safely wrap/repeat them horizontally.
@ -71,7 +74,8 @@ public:
SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; } SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; }
GrContext* getContext() const { return fDesc.fContext; } GrContext* getContext() const { return fDesc.fContext; }
GrTexture* getTexture() const { return fTexture; }
sk_sp<GrTextureProxy> asTextureProxyRef() const;
private: private:
@ -168,7 +172,7 @@ private:
const Desc fDesc; const Desc fDesc;
const uint16_t fNumRows; const uint16_t fNumRows;
GrTexture* fTexture; sk_sp<GrSurfaceContext> fTexContext;
SkScalar fNormalizedYHeight; SkScalar fNormalizedYHeight;

View File

@ -375,7 +375,7 @@ public:
const SkBitmap& bitmap, const SkBitmap& bitmap,
unsigned flags); unsigned flags);
virtual ~ColorTableEffect(); ~ColorTableEffect() override;
const char* name() const override { return "ColorTable"; } const char* name() const override { return "ColorTable"; }
@ -389,7 +389,8 @@ private:
bool onIsEqual(const GrFragmentProcessor&) const override; bool onIsEqual(const GrFragmentProcessor&) const override;
ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, unsigned flags); ColorTableEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
GrTextureStripAtlas* atlas, int row, unsigned flags);
GR_DECLARE_FRAGMENT_PROCESSOR_TEST; GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
@ -494,29 +495,27 @@ sk_sp<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context, const SkBi
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps()); desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps());
GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc); GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc);
int row = atlas->lockRow(bitmap); int row = atlas->lockRow(bitmap);
sk_sp<GrTexture> texture; sk_sp<GrTextureProxy> proxy;
if (-1 == row) { if (-1 == row) {
atlas = nullptr; atlas = nullptr;
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(context, bitmap); proxy = GrMakeCachedBitmapProxy(context, bitmap);
if (proxy) {
texture.reset(proxy->instantiate(context->textureProvider()));
}
} else { } else {
texture.reset(SkRef(atlas->getTexture())); proxy = atlas->asTextureProxyRef();
} }
if (!texture) { if (!proxy) {
return nullptr; return nullptr;
} }
return sk_sp<GrFragmentProcessor>(new ColorTableEffect(texture.get(), atlas, row, flags)); return sk_sp<GrFragmentProcessor>(new ColorTableEffect(context, std::move(proxy),
atlas, row, flags));
} }
ColorTableEffect::ColorTableEffect(GrTexture* texture, GrTextureStripAtlas* atlas, int row, ColorTableEffect::ColorTableEffect(GrContext* context, sk_sp<GrTextureProxy> proxy,
unsigned flags) GrTextureStripAtlas* atlas, int row, unsigned flags)
: INHERITED(kNone_OptimizationFlags) // Not bothering with table-specific optimizations. : INHERITED(kNone_OptimizationFlags) // Not bothering with table-specific optimizations.
, fTextureSampler(texture) , fTextureSampler(context->textureProvider(), std::move(proxy))
, fAtlas(atlas) , fAtlas(atlas)
, fRow(row) { , fRow(row) {
this->initClassID<ColorTableEffect>(); this->initClassID<ColorTableEffect>();

View File

@ -8,6 +8,7 @@
#include "Sk4fLinearGradient.h" #include "Sk4fLinearGradient.h"
#include "SkColorSpace_XYZ.h" #include "SkColorSpace_XYZ.h"
#include "SkGradientShaderPriv.h" #include "SkGradientShaderPriv.h"
#include "SkGrPriv.h"
#include "SkHalf.h" #include "SkHalf.h"
#include "SkLinearGradient.h" #include "SkLinearGradient.h"
#include "SkRadialGradient.h" #include "SkRadialGradient.h"
@ -1674,6 +1675,8 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque)
SkBitmap bitmap; SkBitmap bitmap;
shader.getGradientTableBitmap(&bitmap, bitmapType); shader.getGradientTableBitmap(&bitmap, bitmapType);
SkASSERT(1 == bitmap.height() && SkIsPow2(bitmap.width()));
GrTextureStripAtlas::Desc desc; GrTextureStripAtlas::Desc desc;
desc.fWidth = bitmap.width(); desc.fWidth = bitmap.width();
@ -1694,18 +1697,28 @@ GrGradientEffect::GrGradientEffect(const CreateArgs& args, bool isOpaque)
if (-1 != fRow) { if (-1 != fRow) {
fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight(); fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
// This is 1/2 places where auto-normalization is disabled // This is 1/2 places where auto-normalization is disabled
fCoordTransform.reset(*args.fMatrix, fAtlas->getTexture(), fCoordTransform.reset(args.fContext, *args.fMatrix,
fAtlas->asTextureProxyRef().get(),
params.filterMode(), false); params.filterMode(), false);
fTextureSampler.reset(fAtlas->getTexture(), params); fTextureSampler.reset(args.fContext->textureProvider(),
fAtlas->asTextureProxyRef(), params);
} else { } else {
sk_sp<GrTexture> texture(GrRefCachedBitmapTexture(args.fContext, bitmap, // In this instance we know the params are:
params, nullptr)); // clampY, bilerp
if (!texture) { // and the proxy is:
// exact fit, power of two in both dimensions
// Only the x-tileMode is unknown. However, given all the other knowns we know
// that GrMakeCachedBitmapProxy is sufficient (i.e., it won't need to be
// extracted to a subset or mipmapped).
sk_sp<GrTextureProxy> proxy = GrMakeCachedBitmapProxy(args.fContext, bitmap);
if (!proxy) {
return; return;
} }
// This is 2/2 places where auto-normalization is disabled // This is 2/2 places where auto-normalization is disabled
fCoordTransform.reset(*args.fMatrix, texture.get(), params.filterMode(), false); fCoordTransform.reset(args.fContext, *args.fMatrix,
fTextureSampler.reset(texture.get(), params); proxy.get(), params.filterMode(), false);
fTextureSampler.reset(args.fContext->textureProvider(),
std::move(proxy), params);
fYCoord = SK_ScalarHalf; fYCoord = SK_ScalarHalf;
} }

View File

@ -211,9 +211,7 @@ GrProcessor::TextureSampler::TextureSampler(GrTexture* texture,
GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider, GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
sk_sp<GrTextureProxy> proxy, sk_sp<GrTextureProxy> proxy,
const GrSamplerParams& params) { const GrSamplerParams& params) {
// For now, end the deferral at this time. Once all the TextureSamplers are swapped over this->reset(texProvider, std::move(proxy), params);
// to taking a GrSurfaceProxy just use the IORefs on the proxy
this->reset(proxy->instantiate(texProvider), params);
} }
GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider, GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
@ -221,9 +219,7 @@ GrProcessor::TextureSampler::TextureSampler(GrTextureProvider* texProvider,
GrSamplerParams::FilterMode filterMode, GrSamplerParams::FilterMode filterMode,
SkShader::TileMode tileXAndY, SkShader::TileMode tileXAndY,
GrShaderFlags visibility) { GrShaderFlags visibility) {
// For now, end the deferral at this time. Once all the TextureSamplers are swapped over this->reset(texProvider, std::move(proxy), filterMode, tileXAndY, visibility);
// to taking a GrSurfaceProxy just use the IORefs on the proxy
this->reset(proxy->instantiate(texProvider), filterMode, tileXAndY, visibility);
} }
void GrProcessor::TextureSampler::reset(GrTexture* texture, void GrProcessor::TextureSampler::reset(GrTexture* texture,
@ -247,6 +243,35 @@ void GrProcessor::TextureSampler::reset(GrTexture* texture,
fVisibility = visibility; fVisibility = visibility;
} }
void GrProcessor::TextureSampler::reset(GrTextureProvider* texProvider,
sk_sp<GrTextureProxy> proxy,
const GrSamplerParams& params,
GrShaderFlags visibility) {
// For now, end the deferral at this time. Once all the TextureSamplers are swapped over
// to taking a GrSurfaceProxy just use the IORefs on the proxy
GrTexture* texture = proxy->instantiate(texProvider);
SkASSERT(texture);
fTexture.set(SkRef(texture), kRead_GrIOType);
fParams = params;
fParams.setFilterMode(SkTMin(params.filterMode(), texture->texturePriv().highestFilterMode()));
fVisibility = visibility;
}
void GrProcessor::TextureSampler::reset(GrTextureProvider* texProvider,
sk_sp<GrTextureProxy> proxy,
GrSamplerParams::FilterMode filterMode,
SkShader::TileMode tileXAndY,
GrShaderFlags visibility) {
// For now, end the deferral at this time. Once all the TextureSamplers are swapped over
// to taking a GrSurfaceProxy just use the IORefs on the proxy
GrTexture* texture = proxy->instantiate(texProvider);
SkASSERT(texture);
fTexture.set(SkRef(texture), kRead_GrIOType);
filterMode = SkTMin(filterMode, texture->texturePriv().highestFilterMode());
fParams.reset(tileXAndY, filterMode);
fVisibility = visibility;
}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType, GrProcessor::ImageStorageAccess::ImageStorageAccess(sk_sp<GrTexture> texture, GrIOType ioType,

View File

@ -186,15 +186,14 @@ bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBu
// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext? // TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, bool GrRenderTargetContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y) { size_t srcRowBytes, int x, int y, uint32_t flags) {
// TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels // TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps()); GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
if (kUnknown_GrPixelConfig == config) { if (kUnknown_GrPixelConfig == config) {
return false; return false;
} }
uint32_t flags = 0;
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) { if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
flags = GrContext::kUnpremul_PixelOpsFlag; flags |= GrContext::kUnpremul_PixelOpsFlag;
} }
// Deferral of the VRAM resources must end in this instance anyway // Deferral of the VRAM resources must end in this instance anyway

View File

@ -133,15 +133,15 @@ bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext? // TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer, bool GrTextureContext::onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y) { size_t srcRowBytes, int x, int y,
uint32_t flags) {
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels // TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps()); GrPixelConfig config = SkImageInfo2GrPixelConfig(srcInfo, *fContext->caps());
if (kUnknown_GrPixelConfig == config) { if (kUnknown_GrPixelConfig == config) {
return false; return false;
} }
uint32_t flags = 0;
if (kUnpremul_SkAlphaType == srcInfo.alphaType()) { if (kUnpremul_SkAlphaType == srcInfo.alphaType()) {
flags = GrContext::kUnpremul_PixelOpsFlag; flags |= GrContext::kUnpremul_PixelOpsFlag;
} }
// Deferral of the VRAM resources must end in this instance anyway // Deferral of the VRAM resources must end in this instance anyway

View File

@ -7,7 +7,8 @@
#include "GrTextureStripAtlas.h" #include "GrTextureStripAtlas.h"
#include "GrContext.h" #include "GrContext.h"
#include "GrTexture.h" #include "GrContextPriv.h"
#include "GrSurfaceContext.h"
#include "SkGr.h" #include "SkGr.h"
#include "SkPixelRef.h" #include "SkPixelRef.h"
#include "SkTSearch.h" #include "SkTSearch.h"
@ -73,7 +74,6 @@ GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc)
, fLockedRows(0) , fLockedRows(0)
, fDesc(desc) , fDesc(desc)
, fNumRows(desc.fHeight / desc.fRowHeight) , fNumRows(desc.fHeight / desc.fRowHeight)
, fTexture(nullptr)
, fRows(new AtlasRow[fNumRows]) , fRows(new AtlasRow[fNumRows])
, fLRUFront(nullptr) , fLRUFront(nullptr)
, fLRUBack(nullptr) { , fLRUBack(nullptr) {
@ -85,16 +85,16 @@ GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc)
GrTextureStripAtlas::~GrTextureStripAtlas() { delete[] fRows; } GrTextureStripAtlas::~GrTextureStripAtlas() { delete[] fRows; }
int GrTextureStripAtlas::lockRow(const SkBitmap& data) { int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) {
VALIDATE; VALIDATE;
if (0 == fLockedRows) { if (0 == fLockedRows) {
this->lockTexture(); this->lockTexture();
if (!fTexture) { if (!fTexContext) {
return -1; return -1;
} }
} }
int key = data.getGenerationID(); int key = bitmap.getGenerationID();
int rowNumber = -1; int rowNumber = -1;
int index = this->searchByKey(key); int index = this->searchByKey(key);
@ -152,16 +152,16 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
fKeyTable.insert(index, 1, &row); fKeyTable.insert(index, 1, &row);
rowNumber = static_cast<int>(row - fRows); rowNumber = static_cast<int>(row - fRows);
SkAutoLockPixels lock(data); SkAutoLockPixels lock(bitmap);
SkASSERT(bitmap.width() == fDesc.fWidth);
SkASSERT(bitmap.height() == fDesc.fRowHeight);
// Pass in the kDontFlush flag, since we know we're writing to a part of this texture // Pass in the kDontFlush flag, since we know we're writing to a part of this texture
// that is not currently in use // that is not currently in use
fTexture->writePixels(0, rowNumber * fDesc.fRowHeight, fTexContext->writePixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(),
fDesc.fWidth, fDesc.fRowHeight, 0, rowNumber * fDesc.fRowHeight,
SkImageInfo2GrPixelConfig(data.info(), *this->getContext()->caps()), GrContext::kDontFlush_PixelOpsFlag);
data.getPixels(),
data.rowBytes(),
GrContext::kDontFlush_PixelOpsFlag);
} }
SkASSERT(rowNumber >= 0); SkASSERT(rowNumber >= 0);
@ -169,6 +169,10 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& data) {
return rowNumber; return rowNumber;
} }
sk_sp<GrTextureProxy> GrTextureStripAtlas::asTextureProxyRef() const {
return fTexContext->asTextureProxyRef();
}
void GrTextureStripAtlas::unlockRow(int row) { void GrTextureStripAtlas::unlockRow(int row) {
VALIDATE; VALIDATE;
--fRows[row].fLocks; --fRows[row].fLocks;
@ -202,29 +206,30 @@ void GrTextureStripAtlas::lockTexture() {
builder[0] = static_cast<uint32_t>(fCacheKey); builder[0] = static_cast<uint32_t>(fCacheKey);
builder.finish(); builder.finish();
fTexture = fDesc.fContext->textureProvider()->findAndRefTextureByUniqueKey(key); // MDB TODO (caching): this side-steps the issue of proxies with unique IDs
if (nullptr == fTexture) { GrTexture* texture = fDesc.fContext->textureProvider()->findAndRefTextureByUniqueKey(key);
fTexture = fDesc.fContext->textureProvider()->createTexture(texDesc, SkBudgeted::kYes, if (!texture) {
nullptr, 0); texture = fDesc.fContext->textureProvider()->createTexture(texDesc, SkBudgeted::kYes,
if (!fTexture) { nullptr, 0);
if (!texture) {
return; return;
} }
// We will be issuing writes to the surface using kDontFlush_PixelOpsFlag, so we // We will be issuing writes to the surface using kDontFlush_PixelOpsFlag, so we
// need to make sure any existing IO is flushed // need to make sure any existing IO is flushed
fDesc.fContext->flushSurfaceIO(fTexture); fDesc.fContext->flushSurfaceIO(texture);
fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, fTexture); fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, texture);
// This is a new texture, so all of our cache info is now invalid // This is a new texture, so all of our cache info is now invalid
this->initLRU(); this->initLRU();
fKeyTable.rewind(); fKeyTable.rewind();
} }
SkASSERT(fTexture); SkASSERT(texture);
fTexContext = fDesc.fContext->contextPriv().makeWrappedSurfaceContext(sk_ref_sp(texture));
} }
void GrTextureStripAtlas::unlockTexture() { void GrTextureStripAtlas::unlockTexture() {
SkASSERT(fTexture && 0 == fLockedRows); SkASSERT(fTexContext && 0 == fLockedRows);
fTexture->unref(); fTexContext.reset();
fTexture = nullptr;
} }
void GrTextureStripAtlas::initLRU() { void GrTextureStripAtlas::initLRU() {
@ -348,9 +353,9 @@ void GrTextureStripAtlas::validate() {
// If we have locked rows, we should have a locked texture, otherwise // If we have locked rows, we should have a locked texture, otherwise
// it should be unlocked // it should be unlocked
if (fLockedRows == 0) { if (fLockedRows == 0) {
SkASSERT(nullptr == fTexture); SkASSERT(!fTexContext);
} else { } else {
SkASSERT(fTexture); SkASSERT(fTexContext);
} }
} }
#endif #endif

View File

@ -52,6 +52,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo)
} }
srcSurface = srcProxy->instantiate(context->textureProvider()); srcSurface = srcProxy->instantiate(context->textureProvider());
// TODO: maybe add an assert here on srcSurface's ref state to ensure it is what we
// expect.
srcProxy.reset(); srcProxy.reset();
} }
@ -64,7 +66,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo)
atlasDesc.fConfig = desc.fConfig; atlasDesc.fConfig = desc.fConfig;
atlasDesc.fWidth = desc.fWidth; atlasDesc.fWidth = desc.fWidth;
atlasDesc.fHeight = desc.fHeight; atlasDesc.fHeight = desc.fHeight;
atlasDesc.fRowHeight = 1; atlasDesc.fRowHeight = desc.fHeight;
atlas = GrTextureStripAtlas::GetAtlas(atlasDesc); atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
} }
@ -73,10 +75,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo)
{ {
SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType); SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
SkBitmap bitmap; SkBitmap bitmap;
bitmap.allocPixels(info, rowBytes); bitmap.allocPixels(info);
memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight); bitmap.eraseColor(SK_ColorBLACK);
lockedRow = atlas->lockRow(bitmap); lockedRow = atlas->lockRow(bitmap);
} }
@ -103,8 +104,11 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo)
} }
if (!context->caps()->preferVRAMUseOverFlushes()) { if (!context->caps()->preferVRAMUseOverFlushes()) {
sk_sp<GrTextureProxy> proxy = atlas->asTextureProxyRef();
GrTexture* tex = proxy->instantiate(context->textureProvider());
// This is kindof dodgy since we released it! // This is kindof dodgy since we released it!
REPORTER_ASSERT(reporter, srcSurface == atlas->getTexture()); REPORTER_ASSERT(reporter, srcSurface == tex);
} }
atlas->unlockRow(lockedRow); atlas->unlockRow(lockedRow);

View File

@ -50,10 +50,11 @@ public:
static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> child) { static sk_sp<GrFragmentProcessor> Make(sk_sp<GrFragmentProcessor> child) {
return sk_sp<GrFragmentProcessor>(new TestFP(std::move(child))); return sk_sp<GrFragmentProcessor>(new TestFP(std::move(child)));
} }
static sk_sp<GrFragmentProcessor> Make(const SkTArray<sk_sp<GrTexture>>& textures, static sk_sp<GrFragmentProcessor> Make(GrContext* context,
const SkTArray<sk_sp<GrTextureProxy>>& proxies,
const SkTArray<sk_sp<GrBuffer>>& buffers, const SkTArray<sk_sp<GrBuffer>>& buffers,
const SkTArray<Image>& images) { const SkTArray<Image>& images) {
return sk_sp<GrFragmentProcessor>(new TestFP(textures, buffers, images)); return sk_sp<GrFragmentProcessor>(new TestFP(context, proxies, buffers, images));
} }
const char* name() const override { return "test"; } const char* name() const override { return "test"; }
@ -65,11 +66,13 @@ public:
} }
private: private:
TestFP(const SkTArray<sk_sp<GrTexture>>& textures, const SkTArray<sk_sp<GrBuffer>>& buffers, TestFP(GrContext* context,
const SkTArray<sk_sp<GrTextureProxy>>& proxies,
const SkTArray<sk_sp<GrBuffer>>& buffers,
const SkTArray<Image>& images) const SkTArray<Image>& images)
: INHERITED(kNone_OptimizationFlags), fSamplers(4), fBuffers(4), fImages(4) { : INHERITED(kNone_OptimizationFlags), fSamplers(4), fBuffers(4), fImages(4) {
for (const auto& texture : textures) { for (const auto& proxy : proxies) {
this->addTextureSampler(&fSamplers.emplace_back(texture.get())); this->addTextureSampler(&fSamplers.emplace_back(context->textureProvider(), proxy));
} }
for (const auto& buffer : buffers) { for (const auto& buffer : buffers) {
this->addBufferAccess(&fBuffers.emplace_back(kRGBA_8888_GrPixelConfig, buffer.get())); this->addBufferAccess(&fBuffers.emplace_back(kRGBA_8888_GrPixelConfig, buffer.get()));
@ -115,6 +118,12 @@ inline void testingOnly_getIORefCnts(const T* resource, int* refCnt, int* readCn
*writeCnt = resource->fPendingWrites; *writeCnt = resource->fPendingWrites;
} }
void testingOnly_getIORefCnts(GrSurfaceProxy* proxy, int* refCnt, int* readCnt, int* writeCnt) {
*refCnt = proxy->getBackingRefCnt_TestOnly();
*readCnt = proxy->getPendingReadCnt_TestOnly();
*writeCnt = proxy->getPendingWriteCnt_TestOnly();
}
DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) { DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext(); GrContext* context = ctxInfo.grContext();
@ -129,8 +138,9 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
{ {
bool texelBufferSupport = context->caps()->shaderCaps()->texelBufferSupport(); bool texelBufferSupport = context->caps()->shaderCaps()->texelBufferSupport();
bool imageLoadStoreSupport = context->caps()->shaderCaps()->imageLoadStoreSupport(); bool imageLoadStoreSupport = context->caps()->shaderCaps()->imageLoadStoreSupport();
sk_sp<GrTexture> texture1( sk_sp<GrSurfaceProxy> proxy1(GrSurfaceProxy::MakeDeferred(*context->caps(), desc,
context->resourceProvider()->createTexture(desc, SkBudgeted::kYes)); SkBackingFit::kExact,
SkBudgeted::kYes));
sk_sp<GrTexture> texture2( sk_sp<GrTexture> texture2(
context->resourceProvider()->createTexture(desc, SkBudgeted::kYes)); context->resourceProvider()->createTexture(desc, SkBudgeted::kYes));
sk_sp<GrTexture> texture3( sk_sp<GrTexture> texture3(
@ -143,10 +153,10 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
GrAccessPattern::kStatic_GrAccessPattern, 0) GrAccessPattern::kStatic_GrAccessPattern, 0)
: nullptr); : nullptr);
{ {
SkTArray<sk_sp<GrTexture>> textures; SkTArray<sk_sp<GrTextureProxy>> proxies;
SkTArray<sk_sp<GrBuffer>> buffers; SkTArray<sk_sp<GrBuffer>> buffers;
SkTArray<TestFP::Image> images; SkTArray<TestFP::Image> images;
textures.push_back(texture1); proxies.push_back(sk_ref_sp(proxy1->asTextureProxy()));
if (texelBufferSupport) { if (texelBufferSupport) {
buffers.push_back(buffer); buffers.push_back(buffer);
} }
@ -157,7 +167,8 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
} }
std::unique_ptr<GrDrawOp> op(TestOp::Make()); std::unique_ptr<GrDrawOp> op(TestOp::Make());
GrPaint paint; GrPaint paint;
auto fp = TestFP::Make(std::move(textures), std::move(buffers), std::move(images)); auto fp = TestFP::Make(context,
std::move(proxies), std::move(buffers), std::move(images));
for (int i = 0; i < parentCnt; ++i) { for (int i = 0; i < parentCnt; ++i) {
fp = TestFP::Make(std::move(fp)); fp = TestFP::Make(std::move(fp));
} }
@ -167,7 +178,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
} }
int refCnt, readCnt, writeCnt; int refCnt, readCnt, writeCnt;
testingOnly_getIORefCnts(texture1.get(), &refCnt, &readCnt, &writeCnt); testingOnly_getIORefCnts(proxy1.get(), &refCnt, &readCnt, &writeCnt);
REPORTER_ASSERT(reporter, 1 == refCnt); REPORTER_ASSERT(reporter, 1 == refCnt);
REPORTER_ASSERT(reporter, 1 == readCnt); REPORTER_ASSERT(reporter, 1 == readCnt);
REPORTER_ASSERT(reporter, 0 == writeCnt); REPORTER_ASSERT(reporter, 0 == writeCnt);
@ -198,7 +209,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(ProcessorRefTest, reporter, ctxInfo) {
context->flush(); context->flush();
testingOnly_getIORefCnts(texture1.get(), &refCnt, &readCnt, &writeCnt); testingOnly_getIORefCnts(proxy1.get(), &refCnt, &readCnt, &writeCnt);
REPORTER_ASSERT(reporter, 1 == refCnt); REPORTER_ASSERT(reporter, 1 == refCnt);
REPORTER_ASSERT(reporter, 0 == readCnt); REPORTER_ASSERT(reporter, 0 == readCnt);
REPORTER_ASSERT(reporter, 0 == writeCnt); REPORTER_ASSERT(reporter, 0 == writeCnt);
@ -241,10 +252,10 @@ static GrColor texel_color(int i, int j) {
static GrColor4f texel_color4f(int i, int j) { return GrColor4f::FromGrColor(texel_color(i, j)); } static GrColor4f texel_color4f(int i, int j) { return GrColor4f::FromGrColor(texel_color(i, j)); }
void test_draw_op(GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp, void test_draw_op(GrContext* context, GrRenderTargetContext* rtc, sk_sp<GrFragmentProcessor> fp,
GrTexture* inputDataTexture) { sk_sp<GrTextureProxy> inputDataProxy) {
GrPaint paint; GrPaint paint;
paint.addColorTextureProcessor(inputDataTexture, nullptr, SkMatrix::I()); paint.addColorTextureProcessor(context, std::move(inputDataProxy), nullptr, SkMatrix::I());
paint.addColorFragmentProcessor(std::move(fp)); paint.addColorFragmentProcessor(std::move(fp));
paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
GrPipelineBuilder pb(std::move(paint), GrAAType::kNone); GrPipelineBuilder pb(std::move(paint), GrAAType::kNone);
@ -299,8 +310,12 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ProcessorOptimizationValidationTest, repor
} }
} }
desc.fConfig = kRGBA_8888_GrPixelConfig; desc.fConfig = kRGBA_8888_GrPixelConfig;
sk_sp<GrTexture> dataTexture(context->textureProvider()->createTexture(
desc, SkBudgeted::kYes, rgbaData.get(), 256 * sizeof(GrColor))); sk_sp<GrSurfaceProxy> dataProxy = GrSurfaceProxy::MakeDeferred(*context->caps(),
context->textureProvider(),
desc, SkBudgeted::kYes,
rgbaData.get(),
256 * sizeof(GrColor));
// Because processors factories configure themselves in random ways, this is not exhaustive. // Because processors factories configure themselves in random ways, this is not exhaustive.
for (int i = 0; i < FPFactory::Count(); ++i) { for (int i = 0; i < FPFactory::Count(); ++i) {
@ -319,7 +334,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ProcessorOptimizationValidationTest, repor
!fp->compatibleWithCoverageAsAlpha()) { !fp->compatibleWithCoverageAsAlpha()) {
continue; continue;
} }
test_draw_op(rtc.get(), fp, dataTexture.get()); test_draw_op(context, rtc.get(), fp, sk_ref_sp(dataProxy->asTextureProxy()));
memset(rgbaData.get(), 0x0, sizeof(GrColor) * 256 * 256); memset(rgbaData.get(), 0x0, sizeof(GrColor) * 256 * 256);
rtc->readPixels( rtc->readPixels(
SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kPremul_SkAlphaType), SkImageInfo::Make(256, 256, kRGBA_8888_SkColorType, kPremul_SkAlphaType),