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 | |
10 | namespace flutter { |
11 | |
12 | GPUSurfaceSoftware::GPUSurfaceSoftware(GPUSurfaceSoftwareDelegate* delegate, |
13 | bool render_to_surface) |
14 | : delegate_(delegate), |
15 | render_to_surface_(render_to_surface), |
16 | weak_factory_(this) {} |
17 | |
18 | GPUSurfaceSoftware::~GPUSurfaceSoftware() = default; |
19 | |
20 | // |Surface| |
21 | bool GPUSurfaceSoftware::IsValid() { |
22 | return delegate_ != nullptr; |
23 | } |
24 | |
25 | // |Surface| |
26 | std::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| |
76 | SkMatrix 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| |
85 | GrDirectContext* GPUSurfaceSoftware::GetContext() { |
86 | // There is no GrContext associated with a software surface. |
87 | return nullptr; |
88 | } |
89 | |
90 | // |Surface| |
91 | flutter::ExternalViewEmbedder* GPUSurfaceSoftware::GetExternalViewEmbedder() { |
92 | return delegate_->GetExternalViewEmbedder(); |
93 | } |
94 | |
95 | } // namespace flutter |
96 | |