aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gn/tests.gni1
-rw-r--r--src/effects/SkTableColorFilter.cpp16
-rw-r--r--src/gpu/GrTextureStripAtlas.h17
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp5
-rw-r--r--src/shaders/gradients/SkGradientShader.cpp2
-rw-r--r--src/shaders/gradients/SkGradientShaderPriv.h2
-rw-r--r--tests/TextureStripAtlasManagerTest.cpp76
7 files changed, 100 insertions, 19 deletions
diff --git a/gn/tests.gni b/gn/tests.gni
index 661179e0aa..f20718e017 100644
--- a/gn/tests.gni
+++ b/gn/tests.gni
@@ -261,6 +261,7 @@ tests_sources = [
"$_tests/TextBlobCacheTest.cpp",
"$_tests/TextBlobTest.cpp",
"$_tests/TextureProxyTest.cpp",
+ "$_tests/TextureStripAtlasManagerTest.cpp",
"$_tests/Time.cpp",
"$_tests/TopoSortTest.cpp",
"$_tests/ToSRGBColorFilter.cpp",
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 3896acda59..dda50268fb 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -332,7 +332,7 @@ public:
const char* name() const override { return "ColorTable"; }
- const GrTextureStripAtlas* atlas() const { return fAtlas; }
+ const GrTextureStripAtlas* atlas() const { return fAtlas.get(); }
int atlasRow() const { return fRow; }
std::unique_ptr<GrFragmentProcessor> clone() const override;
@@ -344,12 +344,12 @@ private:
bool onIsEqual(const GrFragmentProcessor&) const override;
- ColorTableEffect(sk_sp<GrTextureProxy> proxy, GrTextureStripAtlas* atlas, int row);
+ ColorTableEffect(sk_sp<GrTextureProxy> proxy, sk_sp<GrTextureStripAtlas> atlas, int row);
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
TextureSampler fTextureSampler;
- GrTextureStripAtlas* fAtlas;
+ sk_sp<GrTextureStripAtlas> fAtlas;
int fRow;
typedef GrFragmentProcessor INHERITED;
@@ -452,7 +452,7 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context,
auto atlasManager = context->contextPriv().textureStripAtlasManager();
- GrTextureStripAtlas* atlas = atlasManager->getAtlas(desc);
+ sk_sp<GrTextureStripAtlas> atlas = atlasManager->refAtlas(desc);
int row = atlas->lockRow(context, bitmap);
sk_sp<GrTextureProxy> proxy;
if (-1 == row) {
@@ -474,14 +474,16 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context,
return nullptr;
}
- return std::unique_ptr<GrFragmentProcessor>(new ColorTableEffect(std::move(proxy), atlas, row));
+ return std::unique_ptr<GrFragmentProcessor>(new ColorTableEffect(std::move(proxy),
+ std::move(atlas), row));
}
-ColorTableEffect::ColorTableEffect(sk_sp<GrTextureProxy> proxy, GrTextureStripAtlas* atlas, int row)
+ColorTableEffect::ColorTableEffect(sk_sp<GrTextureProxy> proxy,
+ sk_sp<GrTextureStripAtlas> atlas, int row)
: INHERITED(kColorTableEffect_ClassID,
kNone_OptimizationFlags) // Not bothering with table-specific optimizations.
, fTextureSampler(std::move(proxy))
- , fAtlas(atlas)
+ , fAtlas(std::move(atlas))
, fRow(row) {
this->addTextureSampler(&fTextureSampler);
}
diff --git a/src/gpu/GrTextureStripAtlas.h b/src/gpu/GrTextureStripAtlas.h
index 7a777b53ba..b948566e27 100644
--- a/src/gpu/GrTextureStripAtlas.h
+++ b/src/gpu/GrTextureStripAtlas.h
@@ -9,8 +9,9 @@
#define GrTextureStripAtlas_DEFINED
#include "SkBitmap.h"
-#include "SkOpts.h"
#include "SkGr.h"
+#include "SkOpts.h"
+#include "SkRefCnt.h"
#include "SkTDArray.h"
#include "SkTDynamicHash.h"
#include "SkTypes.h"
@@ -22,7 +23,7 @@ class GrTextureProxy;
* 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.
*/
-class GrTextureStripAtlas {
+class GrTextureStripAtlas : public SkRefCnt {
public:
/**
* Descriptor struct which we'll use as a hash table key
@@ -87,7 +88,7 @@ private:
* The state of a single row in our cache, next/prev pointers allow these to be chained
* together to represent LRU status
*/
- struct AtlasRow : SkNoncopyable {
+ struct AtlasRow : ::SkNoncopyable {
AtlasRow() : fKey(kEmptyAtlasRowKey), fLocks(0), fNext(nullptr), fPrev(nullptr) { }
// GenerationID of the bitmap that is represented by this row, 0xffffffff means "empty"
uint32_t fKey;
@@ -174,7 +175,7 @@ public:
/**
* Try to find an atlas with the required parameters, creates a new one if necessary
*/
- GrTextureStripAtlas* getAtlas(const GrTextureStripAtlas::Desc&);
+ sk_sp<GrTextureStripAtlas> refAtlas(const GrTextureStripAtlas::Desc&);
private:
void deleteAllAtlases();
@@ -182,11 +183,11 @@ private:
// Hash table entry for atlases
class AtlasEntry : public ::SkNoncopyable {
public:
- AtlasEntry(const GrTextureStripAtlas::Desc& desc, GrTextureStripAtlas* atlas)
+ AtlasEntry(const GrTextureStripAtlas::Desc& desc, sk_sp<GrTextureStripAtlas> atlas)
: fDesc(desc)
- , fAtlas(atlas) {
+ , fAtlas(std::move(atlas)) {
}
- ~AtlasEntry() { delete fAtlas; }
+ ~AtlasEntry() { }
// for SkTDynamicHash
static const GrTextureStripAtlas::Desc& GetKey(const AtlasEntry& entry) {
@@ -197,7 +198,7 @@ private:
}
const GrTextureStripAtlas::Desc fDesc;
- GrTextureStripAtlas* fAtlas;
+ sk_sp<GrTextureStripAtlas> fAtlas;
};
typedef SkTDynamicHash<AtlasEntry, GrTextureStripAtlas::Desc> AtlasHash;
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index cd102fe727..fa2e6fc1b1 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -39,11 +39,12 @@ void GrTextureStripAtlasManager::abandon() {
this->deleteAllAtlases();
}
-GrTextureStripAtlas* GrTextureStripAtlasManager::getAtlas(const GrTextureStripAtlas::Desc& desc) {
+sk_sp<GrTextureStripAtlas> GrTextureStripAtlasManager::refAtlas(
+ const GrTextureStripAtlas::Desc& desc) {
AtlasEntry* entry = fAtlasCache.find(desc);
if (!entry) {
// TODO: Does the AtlasEntry need a copy of the Desc if the GrTextureStripAtlas has one?
- entry = new AtlasEntry(desc, new GrTextureStripAtlas(desc));
+ entry = new AtlasEntry(desc, sk_sp<GrTextureStripAtlas>(new GrTextureStripAtlas(desc)));
fAtlasCache.add(entry);
}
diff --git a/src/shaders/gradients/SkGradientShader.cpp b/src/shaders/gradients/SkGradientShader.cpp
index a6fb4e94bd..114b7c58a1 100644
--- a/src/shaders/gradients/SkGradientShader.cpp
+++ b/src/shaders/gradients/SkGradientShader.cpp
@@ -1298,7 +1298,7 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool
desc.fHeight = 32;
desc.fRowHeight = bitmap.height(); // always 1 here
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fContext->caps());
- fAtlas = atlasManager->getAtlas(desc);
+ fAtlas = atlasManager->refAtlas(desc);
SkASSERT(fAtlas);
// We always filter the gradient table. Each table is one row of a texture, always
diff --git a/src/shaders/gradients/SkGradientShaderPriv.h b/src/shaders/gradients/SkGradientShaderPriv.h
index c015a73bf7..7fef12758a 100644
--- a/src/shaders/gradients/SkGradientShaderPriv.h
+++ b/src/shaders/gradients/SkGradientShaderPriv.h
@@ -334,7 +334,7 @@ private:
GrCoordTransform fCoordTransform;
TextureSampler fTextureSampler;
SkScalar fYCoord;
- GrTextureStripAtlas* fAtlas;
+ sk_sp<GrTextureStripAtlas> fAtlas;
int fRow;
bool fIsOpaque;
diff --git a/tests/TextureStripAtlasManagerTest.cpp b/tests/TextureStripAtlasManagerTest.cpp
new file mode 100644
index 0000000000..d03529f120
--- /dev/null
+++ b/tests/TextureStripAtlasManagerTest.cpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "SkCanvas.h"
+#include "SkGradientShader.h"
+#include "SkPaint.h"
+#include "SkSurface.h"
+#include "SkTableColorFilter.h"
+
+#include "Resources.h"
+#include "Test.h"
+
+#if SK_SUPPORT_GPU // These are all GPU-backend specific tests
+
+
+// The gradient shader will use the texture strip atlas if it has too many colors. Make sure
+// abandoning the context works.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureStripAtlasManagerGradientTest, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+
+ static const SkColor gColors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE,
+ SK_ColorCYAN, SK_ColorMAGENTA, SK_ColorYELLOW,
+ SK_ColorBLACK };
+ static const SkScalar gPos[] = { 0, 0.17f, 0.32f, 0.49f, 0.66f, 0.83f, 1.0f };
+
+ SkPaint p;
+ p.setShader(SkGradientShader::MakeTwoPointConical(SkPoint::Make(0, 0),
+ 1.0f,
+ SkPoint::Make(10.0f, 20.0f),
+ 2.0f,
+ gColors,
+ gPos,
+ 7,
+ SkShader::kClamp_TileMode));
+
+ SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128);
+ auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
+ SkCanvas* canvas = surface->getCanvas();
+
+ SkRect r = SkRect::MakeXYWH(10, 10, 100, 100);
+
+ canvas->drawRect(r, p);
+
+ context->abandonContext();
+}
+
+// The table color filter uses the texture strip atlas. Make sure abandoning the context works.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(TextureStripAtlasManagerColorFilterTest, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+
+ sk_sp<SkImage> img = GetResourceAsImage("images/mandrill_128.png");
+
+
+ uint8_t identity[256];
+ for (int i = 0; i < 256; i++) {
+ identity[i] = i;
+ }
+
+ SkPaint p;
+ p.setColorFilter(SkTableColorFilter::Make(identity));
+
+ SkImageInfo info = SkImageInfo::MakeN32Premul(128, 128);
+ auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info));
+ SkCanvas* canvas = surface->getCanvas();
+
+ canvas->drawImage(std::move(img), 0, 0, &p);
+
+ context->abandonContext();
+}
+
+#endif