skia2/tests/PromiseImageTest.cpp
Brian Osman c7ad40f76f Remove SK_SUPPORT_GPU checks in tool-only code
Most of this is (obviously) not necessary to do, but once
I started, I figured I'd just get it all. Tools (nanobench,
DM, skiaserve), all GMs, benches, and unit tests, plus support
code (command line parsing and config stuff).

This is almost entirely mechanical.

Bug: skia:
Change-Id: I209500f8df8c5bd43f8298ff26440d1c4d7425fb
Reviewed-on: https://skia-review.googlesource.com/131153
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
2018-05-31 18:59:44 +00:00

241 lines
11 KiB
C++

/*
* 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 "Test.h"
#include "GrBackendSurface.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrTest.h"
#include "SkDeferredDisplayListRecorder.h"
#include "SkImage_Gpu.h"
using namespace sk_gpu_test;
struct PromiseTextureChecker {
explicit PromiseTextureChecker(const GrBackendTexture& tex)
: fTexture(tex)
, fFulfillCount(0)
, fReleaseCount(0)
, fDoneCount(0) {}
GrBackendTexture fTexture;
int fFulfillCount;
int fReleaseCount;
int fDoneCount;
static void Fulfill(void* self, GrBackendTexture* outTexture) {
static_cast<PromiseTextureChecker*>(self)->fFulfillCount++;
*outTexture = static_cast<PromiseTextureChecker*>(self)->fTexture;
}
static void Release(void* self) {
static_cast<PromiseTextureChecker*>(self)->fReleaseCount++;
}
static void Done(void* self) {
static_cast<PromiseTextureChecker*>(self)->fDoneCount++;
}
};
// Because Vulkan may delay when it actually calls the ReleaseProcs depending on when command
// buffers finish their work, we need some slight wiggle room in what values we expect for fulfill
// and release counts.
static bool check_fulfill_and_release_cnts(const PromiseTextureChecker& promiseChecker,
bool countsMustBeEqual,
int expectedFulfillCnt,
int expectedReleaseCnt,
bool expectedRequired,
int expectedDoneCnt,
skiatest::Reporter* reporter) {
bool result = true;
int countDiff = promiseChecker.fFulfillCount - promiseChecker.fReleaseCount;
// FulfillCount should always equal ReleaseCount or be at most one higher
if (countDiff != 0) {
if (countsMustBeEqual) {
result = false;
REPORTER_ASSERT(reporter, 0 == countDiff);
} else if (countDiff != 1) {
result = false;
REPORTER_ASSERT(reporter, 0 == countDiff || 1 == countDiff);
}
}
int fulfillDiff = expectedFulfillCnt - promiseChecker.fFulfillCount;
REPORTER_ASSERT(reporter, fulfillDiff >= 0);
if (fulfillDiff != 0) {
if (expectedRequired) {
result = false;
REPORTER_ASSERT(reporter, expectedFulfillCnt == promiseChecker.fFulfillCount);
} else if (fulfillDiff > 1) {
result = false;
REPORTER_ASSERT(reporter, fulfillDiff <= 1);
}
}
int releaseDiff = expectedReleaseCnt - promiseChecker.fReleaseCount;
REPORTER_ASSERT(reporter, releaseDiff >= 0);
if (releaseDiff != 0) {
if (expectedRequired) {
result = false;
REPORTER_ASSERT(reporter, expectedReleaseCnt == promiseChecker.fReleaseCount);
} else if (releaseDiff > 1) {
result = false;
REPORTER_ASSERT(reporter, releaseDiff <= 1);
}
}
if (expectedDoneCnt != promiseChecker.fDoneCount) {
result = false;
REPORTER_ASSERT(reporter, expectedDoneCnt == promiseChecker.fDoneCount);
}
return result;
}
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTest, reporter, ctxInfo) {
const int kWidth = 10;
const int kHeight = 10;
GrContext* ctx = ctxInfo.grContext();
GrGpu* gpu = ctx->contextPriv().getGpu();
for (bool releaseImageEarly : {true, false}) {
GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
nullptr, kWidth, kHeight, kRGBA_8888_GrPixelConfig, true, GrMipMapped::kNo);
REPORTER_ASSERT(reporter, backendTex.isValid());
GrBackendFormat backendFormat = backendTex.format();
REPORTER_ASSERT(reporter, backendFormat.isValid());
PromiseTextureChecker promiseChecker(backendTex);
GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
sk_sp<SkImage> refImg(
SkImage_Gpu::MakePromiseTexture(ctx, backendFormat, kWidth, kHeight,
GrMipMapped::kNo, texOrigin,
kRGBA_8888_SkColorType, kPremul_SkAlphaType,
nullptr,
PromiseTextureChecker::Fulfill,
PromiseTextureChecker::Release,
PromiseTextureChecker::Done,
&promiseChecker));
SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
SkCanvas* canvas = surface->getCanvas();
int expectedFulfillCnt = 0;
int expectedReleaseCnt = 0;
int expectedDoneCnt = 0;
canvas->drawImage(refImg, 0, 0);
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
true,
expectedFulfillCnt,
expectedReleaseCnt,
true,
expectedDoneCnt,
reporter));
bool isVulkan = kVulkan_GrBackend == ctx->contextPriv().getBackend();
canvas->flush();
expectedFulfillCnt++;
expectedReleaseCnt++;
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
!isVulkan,
expectedFulfillCnt,
expectedReleaseCnt,
!isVulkan,
expectedDoneCnt,
reporter));
gpu->testingOnly_flushGpuAndSync();
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
true,
expectedFulfillCnt,
expectedReleaseCnt,
true,
expectedDoneCnt,
reporter));
canvas->drawImage(refImg, 0, 0);
canvas->drawImage(refImg, 0, 0);
canvas->flush();
expectedFulfillCnt++;
expectedReleaseCnt++;
gpu->testingOnly_flushGpuAndSync();
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
true,
expectedFulfillCnt,
expectedReleaseCnt,
true,
expectedDoneCnt,
reporter));
// Now test code path on Vulkan where we released the texture, but the GPU isn't done with
// resource yet and we do another draw. We should only call fulfill on the first draw and
// use the cached GrBackendTexture on the second. Release should only be called after the
// second draw is finished.
canvas->drawImage(refImg, 0, 0);
canvas->flush();
expectedFulfillCnt++;
expectedReleaseCnt++;
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
!isVulkan,
expectedFulfillCnt,
expectedReleaseCnt,
!isVulkan,
expectedDoneCnt,
reporter));
canvas->drawImage(refImg, 0, 0);
if (releaseImageEarly) {
refImg.reset();
}
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
!isVulkan,
expectedFulfillCnt,
expectedReleaseCnt,
!isVulkan,
expectedDoneCnt,
reporter));
canvas->flush();
expectedFulfillCnt++;
gpu->testingOnly_flushGpuAndSync();
expectedReleaseCnt++;
if (releaseImageEarly) {
expectedDoneCnt++;
}
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
true,
expectedFulfillCnt,
expectedReleaseCnt,
!isVulkan,
expectedDoneCnt,
reporter));
expectedFulfillCnt = promiseChecker.fFulfillCount;
expectedReleaseCnt = promiseChecker.fReleaseCount;
if (!releaseImageEarly) {
refImg.reset();
expectedDoneCnt++;
}
REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
true,
expectedFulfillCnt,
expectedReleaseCnt,
true,
expectedDoneCnt,
reporter));
gpu->deleteTestingOnlyBackendTexture(backendTex);
}
}