[go: nahoru, domu]

blob: 502016b20cb4fc53cfb3164c0cefd7c4951a5d88 [file] [log] [blame]
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/command_buffer/service/graphite_utils.h"
#include "base/check.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPixmap.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/graphite/Context.h"
#include "third_party/skia/include/gpu/graphite/GraphiteTypes.h"
#include "third_party/skia/include/gpu/graphite/Surface.h"
namespace gpu {
namespace {
struct ReadPixelsContext {
std::unique_ptr<const SkImage::AsyncReadResult> async_result;
bool finished = false;
};
void OnReadPixelsDone(
void* raw_ctx,
std::unique_ptr<const SkImage::AsyncReadResult> async_result) {
ReadPixelsContext* context = reinterpret_cast<ReadPixelsContext*>(raw_ctx);
context->async_result = std::move(async_result);
context->finished = true;
}
// Synchronously read pixels from a graphite image.
template <typename T>
bool GraphiteReadPixelsSyncImpl(skgpu::graphite::Context* context,
skgpu::graphite::Recorder* recorder,
T* imageOrSurface,
const SkImageInfo& dst_info,
void* dst_pointer,
size_t dst_bytes_per_row,
int src_x,
int src_y) {
GraphiteFlush(context, recorder);
ReadPixelsContext read_context;
const SkIRect src_rect =
SkIRect::MakeXYWH(src_x, src_x, dst_info.width(), dst_info.height());
context->asyncRescaleAndReadPixels(
imageOrSurface, dst_info, src_rect, SkImage::RescaleGamma::kSrc,
SkImage::RescaleMode::kRepeatedLinear, &OnReadPixelsDone, &read_context);
context->submit(skgpu::graphite::SyncToCpu::kYes);
CHECK(read_context.finished);
if (!read_context.async_result) {
return false;
}
SkPixmap pixmap(dst_info, read_context.async_result->data(0),
read_context.async_result->rowBytes(0));
return pixmap.readPixels(dst_info, dst_pointer, dst_bytes_per_row);
}
} // namespace
void GraphiteFlush(skgpu::graphite::Context* context,
skgpu::graphite::Recorder* recorder) {
auto recording = recorder->snap();
if (recording) {
context->insertRecording({recording.get()});
}
}
void GraphiteFlushAndSubmit(skgpu::graphite::Context* context,
skgpu::graphite::Recorder* recorder) {
GraphiteFlush(context, recorder);
context->submit();
}
bool GraphiteReadPixelsSync(skgpu::graphite::Context* context,
skgpu::graphite::Recorder* recorder,
SkImage* image,
const SkImageInfo& dst_info,
void* dst_pointer,
size_t dst_bytes_per_row,
int src_x,
int src_y) {
return GraphiteReadPixelsSyncImpl(context, recorder, image, dst_info,
dst_pointer, dst_bytes_per_row, src_x,
src_y);
}
bool GraphiteReadPixelsSync(skgpu::graphite::Context* context,
skgpu::graphite::Recorder* recorder,
SkSurface* surface,
const SkImageInfo& dst_info,
void* dst_pointer,
size_t dst_bytes_per_row,
int src_x,
int src_y) {
return GraphiteReadPixelsSyncImpl(context, recorder, surface, dst_info,
dst_pointer, dst_bytes_per_row, src_x,
src_y);
}
} // namespace gpu