1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
|
// 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 "gpu/command_buffer/service/graphite_shared_context.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(GraphiteSharedContext* 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->asyncRescaleAndReadPixelsAndSubmit(
imageOrSurface, dst_info, src_rect, SkImage::RescaleGamma::kSrc,
SkImage::RescaleMode::kRepeatedLinear, base::BindOnce(&OnReadPixelsDone),
&read_context);
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(GraphiteSharedContext* context,
skgpu::graphite::Recorder* recorder) {
auto recording = recorder->snap();
if (recording) {
context->insertRecording({recording.get()});
}
}
void GraphiteFlushAndSubmit(GraphiteSharedContext* context,
skgpu::graphite::Recorder* recorder) {
GraphiteFlush(context, recorder);
context->submit();
}
bool GraphiteReadPixelsSync(GraphiteSharedContext* 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(GraphiteSharedContext* 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
|