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
This commit is contained in:
parent
9d15dab754
commit
95243ebb68
@ -66,6 +66,7 @@
|
|||||||
'<(skia_include_path)/private/GrRenderTargetProxy.h',
|
'<(skia_include_path)/private/GrRenderTargetProxy.h',
|
||||||
'<(skia_include_path)/private/GrSurfaceProxy.h',
|
'<(skia_include_path)/private/GrSurfaceProxy.h',
|
||||||
'<(skia_include_path)/private/GrTextureProxy.h',
|
'<(skia_include_path)/private/GrTextureProxy.h',
|
||||||
|
'<(skia_include_path)/private/GrTextureStripAtlas.h',
|
||||||
|
|
||||||
'<(skia_src_path)/gpu/GrAppliedClip.h',
|
'<(skia_src_path)/gpu/GrAppliedClip.h',
|
||||||
'<(skia_src_path)/gpu/GrAuditTrail.cpp',
|
'<(skia_src_path)/gpu/GrAuditTrail.cpp',
|
||||||
@ -306,7 +307,6 @@
|
|||||||
'<(skia_src_path)/gpu/effects/GrTextureDomain.cpp',
|
'<(skia_src_path)/gpu/effects/GrTextureDomain.cpp',
|
||||||
'<(skia_src_path)/gpu/effects/GrTextureDomain.h',
|
'<(skia_src_path)/gpu/effects/GrTextureDomain.h',
|
||||||
'<(skia_src_path)/gpu/effects/GrTextureStripAtlas.cpp',
|
'<(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/GrXfermodeFragmentProcessor.cpp',
|
||||||
'<(skia_src_path)/gpu/effects/GrYUVEffect.cpp',
|
'<(skia_src_path)/gpu/effects/GrYUVEffect.cpp',
|
||||||
'<(skia_src_path)/gpu/effects/GrYUVEffect.h',
|
'<(skia_src_path)/gpu/effects/GrYUVEffect.h',
|
||||||
|
@ -306,6 +306,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
void flushSurfaceWrites(GrSurface* surface);
|
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
|
* Finalizes all pending reads and writes to the surface and also performs an MSAA resolve
|
||||||
* if necessary.
|
* if necessary.
|
||||||
|
@ -334,8 +334,8 @@ sk_sp<SkColorFilter> SkTable_ColorFilter::makeComposed(sk_sp<SkColorFilter> inne
|
|||||||
#include "GrContext.h"
|
#include "GrContext.h"
|
||||||
#include "GrFragmentProcessor.h"
|
#include "GrFragmentProcessor.h"
|
||||||
#include "GrInvariantOutput.h"
|
#include "GrInvariantOutput.h"
|
||||||
|
#include "GrTextureStripAtlas.h"
|
||||||
#include "SkGr.h"
|
#include "SkGr.h"
|
||||||
#include "effects/GrTextureStripAtlas.h"
|
|
||||||
#include "glsl/GrGLSLFragmentProcessor.h"
|
#include "glsl/GrGLSLFragmentProcessor.h"
|
||||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||||
#include "glsl/GrGLSLProgramDataManager.h"
|
#include "glsl/GrGLSLProgramDataManager.h"
|
||||||
|
@ -943,9 +943,9 @@ SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
|
|||||||
|
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
|
|
||||||
#include "effects/GrTextureStripAtlas.h"
|
|
||||||
#include "GrContext.h"
|
#include "GrContext.h"
|
||||||
#include "GrInvariantOutput.h"
|
#include "GrInvariantOutput.h"
|
||||||
|
#include "GrTextureStripAtlas.h"
|
||||||
#include "gl/GrGLContext.h"
|
#include "gl/GrGLContext.h"
|
||||||
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
#include "glsl/GrGLSLFragmentShaderBuilder.h"
|
||||||
#include "glsl/GrGLSLProgramDataManager.h"
|
#include "glsl/GrGLSLProgramDataManager.h"
|
||||||
|
@ -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,
|
int GrContext::getRecommendedSampleCount(GrPixelConfig config,
|
||||||
SkScalar dpi) const {
|
SkScalar dpi) const {
|
||||||
|
@ -209,6 +209,10 @@ void GrTextureStripAtlas::lockTexture() {
|
|||||||
if (!fTexture) {
|
if (!fTexture) {
|
||||||
return;
|
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);
|
fDesc.fContext->textureProvider()->assignUniqueKeyToTexture(key, fTexture);
|
||||||
// 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();
|
||||||
|
70
tests/GrTextureStripAtlasTest.cpp
Normal file
70
tests/GrTextureStripAtlasTest.cpp
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user