• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/platform/embedder/embedder_surface_software.h"
6 
7 #include "flutter/fml/trace_event.h"
8 #include "third_party/skia/include/gpu/GrContext.h"
9 
10 namespace flutter {
11 
EmbedderSurfaceSoftware(SoftwareDispatchTable software_dispatch_table,std::unique_ptr<EmbedderExternalViewEmbedder> external_view_embedder)12 EmbedderSurfaceSoftware::EmbedderSurfaceSoftware(
13     SoftwareDispatchTable software_dispatch_table,
14     std::unique_ptr<EmbedderExternalViewEmbedder> external_view_embedder)
15     : software_dispatch_table_(software_dispatch_table),
16       external_view_embedder_(std::move(external_view_embedder)) {
17   if (!software_dispatch_table_.software_present_backing_store) {
18     return;
19   }
20   valid_ = true;
21 }
22 
23 EmbedderSurfaceSoftware::~EmbedderSurfaceSoftware() = default;
24 
25 // |EmbedderSurface|
IsValid() const26 bool EmbedderSurfaceSoftware::IsValid() const {
27   return valid_;
28 }
29 
30 // |EmbedderSurface|
CreateGPUSurface()31 std::unique_ptr<Surface> EmbedderSurfaceSoftware::CreateGPUSurface() {
32   if (!IsValid()) {
33     return nullptr;
34   }
35 
36   auto surface = std::make_unique<GPUSurfaceSoftware>(this);
37 
38   if (!surface->IsValid()) {
39     return nullptr;
40   }
41 
42   return surface;
43 }
44 
45 // |EmbedderSurface|
CreateResourceContext() const46 sk_sp<GrContext> EmbedderSurfaceSoftware::CreateResourceContext() const {
47   return nullptr;
48 }
49 
50 // |GPUSurfaceSoftwareDelegate|
AcquireBackingStore(const SkISize & size)51 sk_sp<SkSurface> EmbedderSurfaceSoftware::AcquireBackingStore(
52     const SkISize& size) {
53   TRACE_EVENT0("flutter", "EmbedderSurfaceSoftware::AcquireBackingStore");
54   if (!IsValid()) {
55     FML_LOG(ERROR)
56         << "Could not acquire backing store for the software surface.";
57     return nullptr;
58   }
59 
60   if (sk_surface_ != nullptr &&
61       SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
62     // The old and new surface sizes are the same. Nothing to do here.
63     return sk_surface_;
64   }
65 
66   SkImageInfo info = SkImageInfo::MakeN32(
67       size.fWidth, size.fHeight, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
68   sk_surface_ = SkSurface::MakeRaster(info, nullptr);
69 
70   if (sk_surface_ == nullptr) {
71     FML_LOG(ERROR) << "Could not create backing store for software rendering.";
72     return nullptr;
73   }
74 
75   return sk_surface_;
76 }
77 
78 // |GPUSurfaceSoftwareDelegate|
PresentBackingStore(sk_sp<SkSurface> backing_store)79 bool EmbedderSurfaceSoftware::PresentBackingStore(
80     sk_sp<SkSurface> backing_store) {
81   if (!IsValid()) {
82     FML_LOG(ERROR) << "Tried to present an invalid software surface.";
83     return false;
84   }
85 
86   SkPixmap pixmap;
87   if (!backing_store->peekPixels(&pixmap)) {
88     FML_LOG(ERROR) << "Could not peek the pixels of the backing store.";
89     return false;
90   }
91 
92   // Some basic sanity checking.
93   uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4;
94 
95   const size_t pixmap_size = pixmap.computeByteSize();
96 
97   if (expected_pixmap_data_size != pixmap_size) {
98     FML_LOG(ERROR) << "Software backing store had unexpected size.";
99     return false;
100   }
101 
102   return software_dispatch_table_.software_present_backing_store(
103       pixmap.addr(),      //
104       pixmap.rowBytes(),  //
105       pixmap.height()     //
106   );
107 }
108 
109 // |GPUSurfaceSoftwareDelegate|
GetExternalViewEmbedder()110 ExternalViewEmbedder* EmbedderSurfaceSoftware::GetExternalViewEmbedder() {
111   return external_view_embedder_.get();
112 }
113 
114 }  // namespace flutter
115