aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar ajuma <ajuma@chromium.org>2016-08-24 08:19:02 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-24 08:19:03 -0700
commit95243ebb68cae9ff4821ea57b9a32a194f2a87cf (patch)
tree65264449e2c7f59145c9985739a6d44513f076f0
parent9d15dab754f9d2633d34db041dc453249dd7e8ac (diff)
Make GrTextureStripAtlas flush pending IO on newly acquired texture
GrTextureStripAtlas uses its own lock counts to protect against overwriting its own earlier writes, but that doesn't protect against IO that was pending when a texture was first acquired. BUG=chromium:637678 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2262233002 Review-Url: https://codereview.chromium.org/2262233002
-rw-r--r--gyp/gpu.gypi2
-rw-r--r--include/gpu/GrContext.h6
-rw-r--r--include/private/GrTextureStripAtlas.h (renamed from src/gpu/effects/GrTextureStripAtlas.h)0
-rw-r--r--src/effects/SkTableColorFilter.cpp2
-rw-r--r--src/effects/gradients/SkGradientShader.cpp2
-rw-r--r--src/gpu/GrContext.cpp8
-rw-r--r--src/gpu/effects/GrTextureStripAtlas.cpp4
-rw-r--r--tests/GrTextureStripAtlasTest.cpp70
8 files changed, 91 insertions, 3 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 9d7a08465b..eb99cfeb0f 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -66,6 +66,7 @@
'<(skia_include_path)/private/GrRenderTargetProxy.h',
'<(skia_include_path)/private/GrSurfaceProxy.h',
'<(skia_include_path)/private/GrTextureProxy.h',
+ '<(skia_include_path)/private/GrTextureStripAtlas.h',
'<(skia_src_path)/gpu/GrAppliedClip.h',
'<(skia_src_path)/gpu/GrAuditTrail.cpp',
@@ -306,7 +307,6 @@
'<(skia_src_path)/gpu/effects/GrTextureDomain.cpp',
'<(skia_src_path)/gpu/effects/GrTextureDomain.h',
'<(skia_src_path)/gpu/effects/GrTextureStripAtlas.cpp',
- '<(skia_src_path)/gpu/effects/GrTextureStripAtlas.h',
'<(skia_src_path)/gpu/effects/GrXfermodeFragmentProcessor.cpp',
'<(skia_src_path)/gpu/effects/GrYUVEffect.cpp',
'<(skia_src_path)/gpu/effects/GrYUVEffect.h',
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index a34a43733a..41292fe5cd 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -307,6 +307,12 @@ public:
void flushSurfaceWrites(GrSurface* surface);
/**
+ * After this returns any pending reads or writes to the surface will have been issued to the
+ * backend 3D API.
+ */
+ void flushSurfaceIO(GrSurface* surface);
+
+ /**
* Finalizes all pending reads and writes to the surface and also performs an MSAA resolve
* if necessary.
*
diff --git a/src/gpu/effects/GrTextureStripAtlas.h b/include/private/GrTextureStripAtlas.h
index 5b90a342d7..5b90a342d7 100644
--- a/src/gpu/effects/GrTextureStripAtlas.h
+++ b/include/private/GrTextureStripAtlas.h
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 20d11f101b..ebf646b999 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -334,8 +334,8 @@ sk_sp<SkColorFilter> SkTable_ColorFilter::makeComposed(sk_sp<SkColorFilter> inne
#include "GrContext.h"
#include "GrFragmentProcessor.h"
#include "GrInvariantOutput.h"
+#include "GrTextureStripAtlas.h"
#include "SkGr.h"
-#include "effects/GrTextureStripAtlas.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
diff --git a/src/effects/gradients/SkGradientShader.cpp b/src/effects/gradients/SkGradientShader.cpp
index a0cbe974f2..eccc21ac6e 100644
--- a/src/effects/gradients/SkGradientShader.cpp
+++ b/src/effects/gradients/SkGradientShader.cpp
@@ -943,9 +943,9 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#if SK_SUPPORT_GPU
-#include "effects/GrTextureStripAtlas.h"
#include "GrContext.h"
#include "GrInvariantOutput.h"
+#include "GrTextureStripAtlas.h"
#include "gl/GrGLContext.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#include "glsl/GrGLSLProgramDataManager.h"
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 06c27ea2cf..5f4e663580 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -594,6 +594,14 @@ void GrContext::flushSurfaceWrites(GrSurface* surface) {
}
}
+void GrContext::flushSurfaceIO(GrSurface* surface) {
+ ASSERT_SINGLE_OWNER
+ RETURN_IF_ABANDONED
+ if (surface->surfacePriv().hasPendingIO()) {
+ this->flush();
+ }
+}
+
////////////////////////////////////////////////////////////////////////////////
int GrContext::getRecommendedSampleCount(GrPixelConfig config,
SkScalar dpi) const {
diff --git a/src/gpu/effects/GrTextureStripAtlas.cpp b/src/gpu/effects/GrTextureStripAtlas.cpp
index 1543a2e9db..2c882508f5 100644
--- a/src/gpu/effects/GrTextureStripAtlas.cpp
+++ b/src/gpu/effects/GrTextureStripAtlas.cpp
@@ -209,6 +209,10 @@ void GrTextureStripAtlas::lockTexture() {
if (!fTexture) {
return;
}
+
+ // We will be issuing writes to the surface using kDontFlush_PixelOpsFlag, so we
+ // need to make sure any existing IO is flushed
+ fDesc.fContext->flushSurfaceIO(fTexture);
fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, fTexture);
// This is a new texture, so all of our cache info is now invalid
this->initLRU();
diff --git a/tests/GrTextureStripAtlasTest.cpp b/tests/GrTextureStripAtlasTest.cpp
new file mode 100644
index 0000000000..a6e98207a0
--- /dev/null
+++ b/tests/GrTextureStripAtlasTest.cpp
@@ -0,0 +1,70 @@
+/*
+ * 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 "GrContext.h"
+#include "GrGpu.h"
+#include "GrTextureStripAtlas.h"
+#include "GrTypes.h"
+#include "SkGpuDevice.h"
+
+// This tests that GrTextureStripAtlas flushes pending IO on the texture it acquires.
+DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) {
+ GrContext* context = ctxInfo.grContext();
+ GrSurfaceDesc desc;
+ desc.fWidth = 32;
+ desc.fHeight = 32;
+ desc.fConfig = kRGBA_8888_GrPixelConfig;
+ GrTexture* texture = context->textureProvider()->createTexture(desc, SkBudgeted::kYes,
+ nullptr, 0);
+
+ GrSurfaceDesc targetDesc = desc;
+ targetDesc.fFlags = kRenderTarget_GrSurfaceFlag;
+ GrTexture* target = context->textureProvider()->createTexture(targetDesc, SkBudgeted::kYes,
+ nullptr, 0);
+
+ SkAutoTMalloc<uint32_t> pixels(desc.fWidth * desc.fHeight);
+ memset(pixels.get(), 0xFF, sizeof(uint32_t) * desc.fWidth * desc.fHeight);
+ texture->writePixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig, pixels.get());
+
+ // Add a pending read to the texture, and then make it available for reuse.
+ context->copySurface(target, texture);
+ texture->unref();
+
+ // Create an atlas with parameters that allow it to reuse the texture.
+ GrTextureStripAtlas::Desc atlasDesc;
+ atlasDesc.fContext = context;
+ atlasDesc.fConfig = desc.fConfig;
+ atlasDesc.fWidth = desc.fWidth;
+ atlasDesc.fHeight = desc.fHeight;
+ atlasDesc.fRowHeight = 1;
+ GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(atlasDesc);
+
+ // Write to the atlas' texture.
+ SkImageInfo info = SkImageInfo::MakeN32(desc.fWidth, desc.fHeight, kPremul_SkAlphaType);
+ size_t rowBytes = desc.fWidth * GrBytesPerPixel(desc.fConfig);
+ SkBitmap bitmap;
+ bitmap.allocPixels(info, rowBytes);
+ memset(bitmap.getPixels(), 1, rowBytes * desc.fHeight);
+ atlas->lockRow(bitmap);
+ if (!context->caps()->preferVRAMUseOverFlushes())
+ REPORTER_ASSERT(reporter, texture == atlas->getTexture());
+
+ // The atlas' use of its texture shouldn't change which pixels got copied to the target.
+ SkAutoTMalloc<uint32_t> actualPixels(desc.fWidth * desc.fHeight);
+ bool success = target->readPixels(0, 0, desc.fWidth, desc.fHeight, kRGBA_8888_GrPixelConfig,
+ actualPixels.get());
+ REPORTER_ASSERT(reporter, success);
+ REPORTER_ASSERT(reporter,
+ !memcmp(pixels.get(), actualPixels.get(),
+ sizeof(uint32_t) * desc.fWidth * desc.fHeight));
+ target->unref();
+}
+
+#endif