blob: 79ff9987664a5aeaf0d3fb500ee5e583ea539fd3 [file] [log] [blame]
/*
* Copyright 2024 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/SkCanvas.h"
#include "include/gpu/graphite/BackendTexture.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Surface.h"
#include "src/core/SkAutoPixmapStorage.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "tools/gpu/ManagedBackendTexture.h"
#include "tools/graphite/GraphiteTestContext.h"
using namespace skgpu;
using namespace skgpu::graphite;
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ImageWrapTextureMipmapsTest,
reporter,
context,
testContext,
true,
CtsEnforcement::kNextRelease) {
auto recorder = context->makeRecorder();
if (!recorder) {
ERRORF(reporter, "Could not make recorder");
return;
}
skgpu::Protected isProtected = skgpu::Protected(context->priv().caps()->protectedSupport());
auto info = SkImageInfo::Make({2, 1}, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
SkAutoPixmapStorage basePM, topPM;
basePM.alloc(info);
basePM.erase(SK_ColorGREEN);
topPM.alloc(info.makeDimensions({1, 1}));
topPM.erase(SK_ColorBLUE);
SkPixmap levelPMs[]{basePM, topPM};
auto mbet = sk_gpu_test::ManagedGraphiteTexture::MakeMipmappedFromPixmaps(recorder.get(),
levelPMs,
Renderable::kNo,
isProtected);
if (!mbet) {
ERRORF(reporter, "Could not make backend texture");
return;
}
std::unique_ptr<Recording> recording = recorder->snap();
auto recordingFinishProc = [](void* context, CallbackResult) {
std::unique_ptr<Recording>(static_cast<Recording*>(context));
};
skgpu::graphite::InsertRecordingInfo recordingInfo;
recordingInfo.fFinishedProc = recordingFinishProc;
recordingInfo.fRecording = recording.get();
recordingInfo.fFinishedContext = recording.release();
if (!context->insertRecording(recordingInfo)) {
ERRORF(reporter, "Could not insert recording");
return;
}
static constexpr struct TestCase {
SkImages::GenerateMipmapsFromBase genMipmaps;
SkColor expectedColor;
} kTestCases[]{{SkImages::GenerateMipmapsFromBase::kNo , 0xFFFF0000},
{SkImages::GenerateMipmapsFromBase::kYes, 0XFF00FF00}};
for (const auto& testCase : kTestCases) {
recorder = context->makeRecorder();
if (!recorder) {
ERRORF(reporter, "Could not make recorder");
return;
}
auto image = SkImages::WrapTexture(recorder.get(),
mbet->texture(),
info.colorType(),
info.alphaType(),
info.refColorSpace(),
Origin::kTopLeft,
testCase.genMipmaps,
sk_gpu_test::ManagedGraphiteTexture::ImageReleaseProc,
mbet->releaseContext());
if (!recorder) {
ERRORF(reporter, "Could not make image");
return;
}
// We determe the contents of the image's top level by doing a downsampling draw to a
// surface and then reading the surface's contents.
auto surface = SkSurfaces::RenderTarget(recorder.get(), info.makeDimensions({1, 1}));
if (!recorder) {
ERRORF(reporter, "Could not make surface");
return;
}
auto shader = image->makeShader(
SkTileMode::kRepeat,
SkTileMode::kRepeat,
SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNearest));
surface->getCanvas()->scale(0.05f, 0.05f);
SkPaint paint;
paint.setShader(std::move(shader));
surface->getCanvas()->drawPaint(paint);
recording = recorder->snap();
recordingInfo.fRecording = recording.get();
recordingInfo.fFinishedContext = recording.release();
if (!context->insertRecording(recordingInfo)) {
ERRORF(reporter, "Could not insert recording");
return;
}
struct ReadContext {
bool called = false;
bool success = false;
uint32_t color;
};
auto readPixelsCallback = [](SkImage::ReadPixelsContext context,
std::unique_ptr<const SkImage::AsyncReadResult> result) {
auto& readContext = *static_cast<ReadContext*>(context);
readContext.called = true;
if (result) {
readContext.success = true;
readContext.color = *static_cast<const uint32_t*>(result->data(0));
}
};
ReadContext readContext;
context->asyncRescaleAndReadPixels(surface.get(),
surface->imageInfo(),
SkIRect::MakeSize(surface->imageInfo().dimensions()),
SkImage::RescaleGamma::kSrc,
SkImage::RescaleMode::kNearest,
readPixelsCallback,
&readContext);
context->submit();
while (!readContext.called) {
testContext->tick();
context->checkAsyncWorkCompletion();
}
if (!readContext.success) {
ERRORF(reporter, "Read pixels failed");
return;
}
REPORTER_ASSERT(reporter, readContext.color == testCase.expectedColor);
}
}