mirror of
https://github.com/encounter/engine.git
synced 2026-03-30 11:09:55 -07:00
139a9a799c
Uses the same technique used during OpenGL composition to elide root surface access. The refactoring of this approach is tracked in https://github.com/flutter/flutter/issues/38466 Fixes https://github.com/flutter/flutter/issues/39009.
115 lines
3.2 KiB
C++
115 lines
3.2 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/platform/embedder/embedder_surface_software.h"
|
|
|
|
#include "flutter/fml/trace_event.h"
|
|
#include "third_party/skia/include/gpu/GrContext.h"
|
|
|
|
namespace flutter {
|
|
|
|
EmbedderSurfaceSoftware::EmbedderSurfaceSoftware(
|
|
SoftwareDispatchTable software_dispatch_table,
|
|
std::unique_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
|
|
: software_dispatch_table_(software_dispatch_table),
|
|
external_view_embedder_(std::move(external_view_embedder)) {
|
|
if (!software_dispatch_table_.software_present_backing_store) {
|
|
return;
|
|
}
|
|
valid_ = true;
|
|
}
|
|
|
|
EmbedderSurfaceSoftware::~EmbedderSurfaceSoftware() = default;
|
|
|
|
// |EmbedderSurface|
|
|
bool EmbedderSurfaceSoftware::IsValid() const {
|
|
return valid_;
|
|
}
|
|
|
|
// |EmbedderSurface|
|
|
std::unique_ptr<Surface> EmbedderSurfaceSoftware::CreateGPUSurface() {
|
|
if (!IsValid()) {
|
|
return nullptr;
|
|
}
|
|
const bool render_to_surface = !external_view_embedder_;
|
|
auto surface = std::make_unique<GPUSurfaceSoftware>(this, render_to_surface);
|
|
|
|
if (!surface->IsValid()) {
|
|
return nullptr;
|
|
}
|
|
|
|
return surface;
|
|
}
|
|
|
|
// |EmbedderSurface|
|
|
sk_sp<GrContext> EmbedderSurfaceSoftware::CreateResourceContext() const {
|
|
return nullptr;
|
|
}
|
|
|
|
// |GPUSurfaceSoftwareDelegate|
|
|
sk_sp<SkSurface> EmbedderSurfaceSoftware::AcquireBackingStore(
|
|
const SkISize& size) {
|
|
TRACE_EVENT0("flutter", "EmbedderSurfaceSoftware::AcquireBackingStore");
|
|
if (!IsValid()) {
|
|
FML_LOG(ERROR)
|
|
<< "Could not acquire backing store for the software surface.";
|
|
return nullptr;
|
|
}
|
|
|
|
if (sk_surface_ != nullptr &&
|
|
SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
|
|
// The old and new surface sizes are the same. Nothing to do here.
|
|
return sk_surface_;
|
|
}
|
|
|
|
SkImageInfo info = SkImageInfo::MakeN32(
|
|
size.fWidth, size.fHeight, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
|
|
sk_surface_ = SkSurface::MakeRaster(info, nullptr);
|
|
|
|
if (sk_surface_ == nullptr) {
|
|
FML_LOG(ERROR) << "Could not create backing store for software rendering.";
|
|
return nullptr;
|
|
}
|
|
|
|
return sk_surface_;
|
|
}
|
|
|
|
// |GPUSurfaceSoftwareDelegate|
|
|
bool EmbedderSurfaceSoftware::PresentBackingStore(
|
|
sk_sp<SkSurface> backing_store) {
|
|
if (!IsValid()) {
|
|
FML_LOG(ERROR) << "Tried to present an invalid software surface.";
|
|
return false;
|
|
}
|
|
|
|
SkPixmap pixmap;
|
|
if (!backing_store->peekPixels(&pixmap)) {
|
|
FML_LOG(ERROR) << "Could not peek the pixels of the backing store.";
|
|
return false;
|
|
}
|
|
|
|
// Some basic sanity checking.
|
|
uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4;
|
|
|
|
const size_t pixmap_size = pixmap.computeByteSize();
|
|
|
|
if (expected_pixmap_data_size != pixmap_size) {
|
|
FML_LOG(ERROR) << "Software backing store had unexpected size.";
|
|
return false;
|
|
}
|
|
|
|
return software_dispatch_table_.software_present_backing_store(
|
|
pixmap.addr(), //
|
|
pixmap.rowBytes(), //
|
|
pixmap.height() //
|
|
);
|
|
}
|
|
|
|
// |GPUSurfaceSoftwareDelegate|
|
|
ExternalViewEmbedder* EmbedderSurfaceSoftware::GetExternalViewEmbedder() {
|
|
return external_view_embedder_.get();
|
|
}
|
|
|
|
} // namespace flutter
|