/* * 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/core/SkBitmap.h" #include "include/core/SkFont.h" #include "include/gpu/graphite/Context.h" #include "include/gpu/graphite/Recording.h" #include "include/gpu/graphite/Surface.h" #include "src/gpu/graphite/ContextPriv.h" #include "src/gpu/graphite/Surface_Graphite.h" #include "tests/TestUtils.h" #include "tools/ToolUtils.h" #include "tools/fonts/FontToolUtils.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 surface = SkSurfaces::RenderTarget(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 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::CreatePortableTypeface("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 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 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(); if (!surface->readPixels(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 (!surface->readPixels(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([&](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_RENDERING_CONTEXTS(RecordingOrderTest_Graphite, reporter, context, CtsEnforcement::kApiLevel_V) { std::unique_ptr recorder = context->makeRecorder(); (void) run_test(reporter, context, recorder.get()); }