mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This is part of a larger effort to expose the difference between GrDirectContext, which runs on the GPU thread and can directly perform operations like uploading textures, and GrRecordingContext, which can only queue up work to be delivered to the GrDirectContext later.
96 lines
2.8 KiB
C++
96 lines
2.8 KiB
C++
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "flutter/shell/gpu/gpu_surface_software.h"
|
|
|
|
#include <memory>
|
|
#include "flutter/fml/logging.h"
|
|
|
|
namespace flutter {
|
|
|
|
GPUSurfaceSoftware::GPUSurfaceSoftware(GPUSurfaceSoftwareDelegate* delegate,
|
|
bool render_to_surface)
|
|
: delegate_(delegate),
|
|
render_to_surface_(render_to_surface),
|
|
weak_factory_(this) {}
|
|
|
|
GPUSurfaceSoftware::~GPUSurfaceSoftware() = default;
|
|
|
|
// |Surface|
|
|
bool GPUSurfaceSoftware::IsValid() {
|
|
return delegate_ != nullptr;
|
|
}
|
|
|
|
// |Surface|
|
|
std::unique_ptr<SurfaceFrame> GPUSurfaceSoftware::AcquireFrame(
|
|
const SkISize& logical_size) {
|
|
// TODO(38466): Refactor GPU surface APIs take into account the fact that an
|
|
// external view embedder may want to render to the root surface.
|
|
if (!render_to_surface_) {
|
|
return std::make_unique<SurfaceFrame>(
|
|
nullptr, true, [](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
|
|
return true;
|
|
});
|
|
}
|
|
|
|
if (!IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
const auto size = SkISize::Make(logical_size.width(), logical_size.height());
|
|
|
|
sk_sp<SkSurface> backing_store = delegate_->AcquireBackingStore(size);
|
|
|
|
if (backing_store == nullptr) {
|
|
return nullptr;
|
|
}
|
|
|
|
if (size != SkISize::Make(backing_store->width(), backing_store->height())) {
|
|
return nullptr;
|
|
}
|
|
|
|
// If the surface has been scaled, we need to apply the inverse scaling to the
|
|
// underlying canvas so that coordinates are mapped to the same spot
|
|
// irrespective of surface scaling.
|
|
SkCanvas* canvas = backing_store->getCanvas();
|
|
canvas->resetMatrix();
|
|
|
|
SurfaceFrame::SubmitCallback on_submit =
|
|
[self = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
|
|
SkCanvas* canvas) -> bool {
|
|
// If the surface itself went away, there is nothing more to do.
|
|
if (!self || !self->IsValid() || canvas == nullptr) {
|
|
return false;
|
|
}
|
|
|
|
canvas->flush();
|
|
|
|
return self->delegate_->PresentBackingStore(surface_frame.SkiaSurface());
|
|
};
|
|
|
|
return std::make_unique<SurfaceFrame>(backing_store, true, on_submit);
|
|
}
|
|
|
|
// |Surface|
|
|
SkMatrix GPUSurfaceSoftware::GetRootTransformation() const {
|
|
// This backend does not currently support root surface transformations. Just
|
|
// return identity.
|
|
SkMatrix matrix;
|
|
matrix.reset();
|
|
return matrix;
|
|
}
|
|
|
|
// |Surface|
|
|
GrDirectContext* GPUSurfaceSoftware::GetContext() {
|
|
// There is no GrContext associated with a software surface.
|
|
return nullptr;
|
|
}
|
|
|
|
// |Surface|
|
|
flutter::ExternalViewEmbedder* GPUSurfaceSoftware::GetExternalViewEmbedder() {
|
|
return delegate_->GetExternalViewEmbedder();
|
|
}
|
|
|
|
} // namespace flutter
|