1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/shell/gpu/gpu_surface_software.h"
6
7#include <memory>
8#include "flutter/fml/logging.h"
9
10namespace flutter {
11
12GPUSurfaceSoftware::GPUSurfaceSoftware(GPUSurfaceSoftwareDelegate* delegate,
13 bool render_to_surface)
14 : delegate_(delegate),
15 render_to_surface_(render_to_surface),
16 weak_factory_(this) {}
17
18GPUSurfaceSoftware::~GPUSurfaceSoftware() = default;
19
20// |Surface|
21bool GPUSurfaceSoftware::IsValid() {
22 return delegate_ != nullptr;
23}
24
25// |Surface|
26std::unique_ptr<SurfaceFrame> GPUSurfaceSoftware::AcquireFrame(
27 const SkISize& logical_size) {
28 // TODO(38466): Refactor GPU surface APIs take into account the fact that an
29 // external view embedder may want to render to the root surface.
30 if (!render_to_surface_) {
31 return std::make_unique<SurfaceFrame>(
32 nullptr, true, [](const SurfaceFrame& surface_frame, SkCanvas* canvas) {
33 return true;
34 });
35 }
36
37 if (!IsValid()) {
38 return nullptr;
39 }
40
41 const auto size = SkISize::Make(logical_size.width(), logical_size.height());
42
43 sk_sp<SkSurface> backing_store = delegate_->AcquireBackingStore(size);
44
45 if (backing_store == nullptr) {
46 return nullptr;
47 }
48
49 if (size != SkISize::Make(backing_store->width(), backing_store->height())) {
50 return nullptr;
51 }
52
53 // If the surface has been scaled, we need to apply the inverse scaling to the
54 // underlying canvas so that coordinates are mapped to the same spot
55 // irrespective of surface scaling.
56 SkCanvas* canvas = backing_store->getCanvas();
57 canvas->resetMatrix();
58
59 SurfaceFrame::SubmitCallback on_submit =
60 [self = weak_factory_.GetWeakPtr()](const SurfaceFrame& surface_frame,
61 SkCanvas* canvas) -> bool {
62 // If the surface itself went away, there is nothing more to do.
63 if (!self || !self->IsValid() || canvas == nullptr) {
64 return false;
65 }
66
67 canvas->flush();
68
69 return self->delegate_->PresentBackingStore(surface_frame.SkiaSurface());
70 };
71
72 return std::make_unique<SurfaceFrame>(backing_store, true, on_submit);
73}
74
75// |Surface|
76SkMatrix GPUSurfaceSoftware::GetRootTransformation() const {
77 // This backend does not currently support root surface transformations. Just
78 // return identity.
79 SkMatrix matrix;
80 matrix.reset();
81 return matrix;
82}
83
84// |Surface|
85GrDirectContext* GPUSurfaceSoftware::GetContext() {
86 // There is no GrContext associated with a software surface.
87 return nullptr;
88}
89
90// |Surface|
91flutter::ExternalViewEmbedder* GPUSurfaceSoftware::GetExternalViewEmbedder() {
92 return delegate_->GetExternalViewEmbedder();
93}
94
95} // namespace flutter
96