skia2/tests/ProxyRefTest.cpp
Robert Phillips 1119dc366e Remove discard from GrRenderTarget & force it to always go through a RenderTargetContext
This is a bit sloppy in that it ignores some instances where discards were being issued before.

The creation of the temp RTContext in the RenderTarget's discard method was causing an extra split in the opLists.

This is split out of: https://skia-review.googlesource.com/c/10284/ (Omnibus: Remove GrSurface-derived classes from ops)

Change-Id: Ic366d303280635763b0fae238c4df37c04fb8503
Reviewed-on: https://skia-review.googlesource.com/11125
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
2017-04-11 19:38:18 +00:00

192 lines
6.2 KiB
C++

/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
// This is a GPU-backend specific test.
#include "Test.h"
#if SK_SUPPORT_GPU
#include "GrContextPriv.h"
#include "GrRenderTargetPriv.h"
#include "GrRenderTargetProxy.h"
#include "GrResourceProvider.h"
#include "GrSurfaceProxy.h"
#include "GrTextureProxy.h"
int32_t GrIORefProxy::getProxyRefCnt_TestOnly() const {
return fRefCnt;
}
int32_t GrIORefProxy::getBackingRefCnt_TestOnly() const {
if (fTarget) {
return fTarget->fRefCnt;
}
return fRefCnt;
}
int32_t GrIORefProxy::getPendingReadCnt_TestOnly() const {
if (fTarget) {
SkASSERT(!fPendingReads);
return fTarget->fPendingReads;
}
return fPendingReads;
}
int32_t GrIORefProxy::getPendingWriteCnt_TestOnly() const {
if (fTarget) {
SkASSERT(!fPendingWrites);
return fTarget->fPendingWrites;
}
return fPendingWrites;
}
static const int kWidthHeight = 128;
static void check_refs(skiatest::Reporter* reporter,
GrTextureProxy* proxy,
int32_t expectedProxyRefs,
int32_t expectedBackingRefs,
int32_t expectedNumReads,
int32_t expectedNumWrites) {
REPORTER_ASSERT(reporter, proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
REPORTER_ASSERT(reporter, proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
REPORTER_ASSERT(reporter, proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
REPORTER_ASSERT(reporter, proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
SkASSERT(proxy->getProxyRefCnt_TestOnly() == expectedProxyRefs);
SkASSERT(proxy->getBackingRefCnt_TestOnly() == expectedBackingRefs);
SkASSERT(proxy->getPendingReadCnt_TestOnly() == expectedNumReads);
SkASSERT(proxy->getPendingWriteCnt_TestOnly() == expectedNumWrites);
}
static sk_sp<GrTextureProxy> make_deferred(GrContext* context) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = kWidthHeight;
desc.fHeight = kWidthHeight;
desc.fConfig = kRGBA_8888_GrPixelConfig;
return GrSurfaceProxy::MakeDeferred(context->resourceProvider(), desc,
SkBackingFit::kApprox, SkBudgeted::kYes);
}
static sk_sp<GrTextureProxy> make_wrapped(GrContext* context) {
GrSurfaceDesc desc;
desc.fFlags = kRenderTarget_GrSurfaceFlag;
desc.fWidth = kWidthHeight;
desc.fHeight = kWidthHeight;
desc.fConfig = kRGBA_8888_GrPixelConfig;
sk_sp<GrTexture> tex(context->resourceProvider()->createTexture(desc, SkBudgeted::kNo));
return GrSurfaceProxy::MakeWrapped(std::move(tex));
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ProxyRefTest, reporter, ctxInfo) {
GrResourceProvider* provider = ctxInfo.grContext()->resourceProvider();
for (auto make : { make_deferred, make_wrapped }) {
// A single write
{
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
static const int kExpectedReads = 0;
static const int kExpectedWrites = 1;
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
proxy->instantiate(provider);
// In the deferred case, this checks that the refs transfered to the GrSurface
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
}
// A single read
{
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
static const int kExpectedReads = 1;
static const int kExpectedWrites = 0;
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
proxy->instantiate(provider);
// In the deferred case, this checks that the refs transfered to the GrSurface
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
}
// A single read/write pair
{
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
GrPendingIOResource<GrSurfaceProxy, kRW_GrIOType> fRW(proxy.get());
static const int kExpectedReads = 1;
static const int kExpectedWrites = 1;
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
proxy->instantiate(provider);
// In the deferred case, this checks that the refs transferred to the GrSurface
check_refs(reporter, proxy.get(), 1, 1, kExpectedReads, kExpectedWrites);
}
// Multiple normal refs
{
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
proxy->ref();
proxy->ref();
static const int kExpectedReads = 0;
static const int kExpectedWrites = 0;
check_refs(reporter, proxy.get(), 3, 3,kExpectedReads, kExpectedWrites);
proxy->instantiate(provider);
// In the deferred case, this checks that the refs transferred to the GrSurface
check_refs(reporter, proxy.get(), 3, 3, kExpectedReads, kExpectedWrites);
proxy->unref();
proxy->unref();
}
// Continue using (reffing) proxy after instantiation
{
sk_sp<GrTextureProxy> proxy((*make)(ctxInfo.grContext()));
proxy->ref();
GrPendingIOResource<GrSurfaceProxy, kWrite_GrIOType> fWrite(proxy.get());
static const int kExpectedWrites = 1;
check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
proxy->instantiate(provider);
// In the deferred case, this checks that the refs transfered to the GrSurface
check_refs(reporter, proxy.get(), 2, 2, 0, kExpectedWrites);
proxy->unref();
check_refs(reporter, proxy.get(), 1, 1, 0, kExpectedWrites);
GrPendingIOResource<GrSurfaceProxy, kRead_GrIOType> fRead(proxy.get());
check_refs(reporter, proxy.get(), 1, 1, 1, kExpectedWrites);
}
}
}
#endif