blob: ab3a5f1ff3e258dce4ce308cdf5f53d24d67c653 [file] [log] [blame]
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "tests/Test.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recording.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"
using namespace skgpu::graphite;
namespace {
const SkISize kSurfaceSize = { 64, 64 };
constexpr SkColor4f kBackgroundColor = SkColors::kWhite;
bool run_test(skiatest::Reporter* reporter,
Context* context,
Recorder* recorder) {
SkImageInfo ii = SkImageInfo::Make(kSurfaceSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
SkBitmap result0, result1;
result0.allocPixels(ii);
result1.allocPixels(ii);
SkPixmap pm0, pm1;
SkAssertResult(result0.peekPixels(&pm0));
SkAssertResult(result1.peekPixels(&pm1));
sk_sp<SkSurface> surface = SkSurface::MakeGraphite(recorder, ii);
if (!surface) {
ERRORF(reporter, "Surface creation failed");
return false;
}
SkCanvas* canvas = surface->getCanvas();
// Set up a recording to clear the surface
canvas->clear(kBackgroundColor);
std::unique_ptr<Recording> clearRecording = recorder->snap();
if (!clearRecording) {
ERRORF(reporter, "Recording creation failed");
return false;
}
// Draw some text and get recording
SkPaint paint;
paint.setAntiAlias(true);
SkFont font(ToolUtils::create_portable_typeface("serif", SkFontStyle()));
font.setSubpixel(true);
font.setSize(12);
const char* text0 = "Hamburge";
const size_t text0Len = strlen(text0);
canvas->drawSimpleText(text0, text0Len, SkTextEncoding::kUTF8, 3, 20, font, paint);
std::unique_ptr<Recording> text0Recording = recorder->snap();
// Draw some more text and get recording
const char* text1 = "burgefons";
const size_t text1Len = strlen(text1);
canvas->drawSimpleText(text1, text1Len, SkTextEncoding::kUTF8, 3, 40, font, paint);
std::unique_ptr<Recording> text1Recording = recorder->snap();
// Playback 0, then 1, and read pixels
InsertRecordingInfo info;
info.fRecording = clearRecording.get();
context->insertRecording(info);
info.fRecording = text0Recording.get();
context->insertRecording(info);
info.fRecording = text1Recording.get();
context->insertRecording(info);
context->submit();
// For now, we cast and call directly into Surface. Once we have a better idea of
// what the public API for synchronous graphite readPixels we can update this call to use
// that instead.
if (!static_cast<skgpu::graphite::Surface*>(surface.get())->onReadPixels(context,
recorder,
pm0,
0,
0)) {
ERRORF(reporter, "readPixels failed");
return false;
}
// Playback 1, then 0, and read pixels
info.fRecording = clearRecording.get();
context->insertRecording(info);
info.fRecording = text1Recording.get();
context->insertRecording(info);
info.fRecording = text0Recording.get();
context->insertRecording(info);
context->submit();
if (!static_cast<skgpu::graphite::Surface*>(surface.get())->onReadPixels(context,
recorder,
pm1,
0,
0)) {
ERRORF(reporter, "readPixels failed");
return false;
}
// Compare and contrast
float tol = 1.f/256;
const float tols[4] = {tol, tol, tol, tol};
auto error = std::function<ComparePixmapsErrorReporter>([&](int x, int y,
const float diffs[4]) {
SkASSERT(x >= 0 && y >= 0);
ERRORF(reporter,
"Error at %d, %d. Diff in floats: (%f, %f, %f, %f)",
x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
});
ComparePixels(pm0, pm1, tols, error);
return true;
}
} // anonymous namespace
// This test captures two recordings A and B, plays them back as A then B, and B then A,
// and verifies that the result is the same.
DEF_GRAPHITE_TEST_FOR_CONTEXTS(RecordingOrderTest_Graphite, reporter, context) {
std::unique_ptr<Recorder> recorder = context->makeRecorder();
(void) run_test(reporter, context, recorder.get());
}