Flutter Engine
ios_surface_software.mm
Go to the documentation of this file.
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 #import "flutter/shell/platform/darwin/ios/ios_surface_software.h"
6 
7 #include <QuartzCore/CALayer.h>
8 
9 #include <memory>
10 
11 #include "flutter/fml/logging.h"
12 #include "flutter/fml/platform/darwin/cf_utils.h"
13 #include "flutter/fml/trace_event.h"
14 #include "third_party/skia/include/utils/mac/SkCGUtils.h"
15 
16 namespace flutter {
17 
20  std::shared_ptr<IOSContext> context,
21  const std::shared_ptr<FlutterPlatformViewsController>& platform_views_controller)
22  : IOSSurface(std::move(context), platform_views_controller), layer_(std::move(layer)) {}
23 
25 
27  return layer_;
28 }
29 
31  // Nothing to do here. We don't need an external entity to tell us when our
32  // backing store needs to be updated. Instead, we let the frame tell us its
33  // size so we can update to match. This method was added to work around
34  // Android oddities.
35 }
36 
37 std::unique_ptr<Surface> IOSSurfaceSoftware::CreateGPUSurface(GrDirectContext* gr_context) {
38  if (!IsValid()) {
39  return nullptr;
40  }
41 
42  auto surface = std::make_unique<GPUSurfaceSoftware>(this, true /* render to surface */);
43 
44  if (!surface->IsValid()) {
45  return nullptr;
46  }
47 
48  return surface;
49 }
50 
51 sk_sp<SkSurface> IOSSurfaceSoftware::AcquireBackingStore(const SkISize& size) {
52  TRACE_EVENT0("flutter", "IOSSurfaceSoftware::AcquireBackingStore");
53  if (!IsValid()) {
54  return nullptr;
55  }
56 
57  if (sk_surface_ != nullptr &&
58  SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
59  // The old and new surface sizes are the same. Nothing to do here.
60  return sk_surface_;
61  }
62 
63  SkImageInfo info = SkImageInfo::MakeN32(size.fWidth, size.fHeight, kPremul_SkAlphaType,
64  SkColorSpace::MakeSRGB());
65  sk_surface_ = SkSurface::MakeRaster(info, nullptr);
66  return sk_surface_;
67 }
68 
69 bool IOSSurfaceSoftware::PresentBackingStore(sk_sp<SkSurface> backing_store) {
70  TRACE_EVENT0("flutter", "IOSSurfaceSoftware::PresentBackingStore");
71  if (!IsValid() || backing_store == nullptr) {
72  return false;
73  }
74 
75  SkPixmap pixmap;
76  if (!backing_store->peekPixels(&pixmap)) {
77  return false;
78  }
79 
80  // Some basic sanity checking.
81  uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4;
82 
83  const size_t pixmap_size = pixmap.computeByteSize();
84 
85  if (expected_pixmap_data_size != pixmap_size) {
86  return false;
87  }
88 
89  fml::CFRef<CGColorSpaceRef> colorspace(CGColorSpaceCreateDeviceRGB());
90 
91  // Setup the data provider that gives CG a view into the pixmap.
92  fml::CFRef<CGDataProviderRef> pixmap_data_provider(CGDataProviderCreateWithData(
93  nullptr, // info
94  pixmap.addr32(), // data
95  pixmap_size, // size
96  nullptr // release callback
97  ));
98 
99  if (!pixmap_data_provider) {
100  return false;
101  }
102 
103  // Create the CGImageRef representation on the pixmap.
104  fml::CFRef<CGImageRef> pixmap_image(CGImageCreate(pixmap.width(), // width
105  pixmap.height(), // height
106  8, // bits per component
107  32, // bits per pixel
108  pixmap.rowBytes(), // bytes per row
109  colorspace, // colorspace
110  kCGImageAlphaPremultipliedLast, // bitmap info
111  pixmap_data_provider, // data provider
112  nullptr, // decode array
113  false, // should interpolate
114  kCGRenderingIntentDefault // rendering intent
115  ));
116 
117  if (!pixmap_image) {
118  return false;
119  }
120 
121  layer_.get().contents = reinterpret_cast<id>(static_cast<CGImageRef>(pixmap_image));
122 
123  return true;
124 }
125 
126 // |GPUSurfaceSoftwareDelegate|
128  return GetSurfaceExternalViewEmbedder().get();
129 }
130 
131 } // namespace flutter
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
sk_sp< SkSurface > AcquireBackingStore(const SkISize &size) override
Called when the GPU surface needs a new buffer to render a new frame into.
void UpdateStorageSizeIfNecessary() override
Definition: ref_ptr.h:252
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
std::unique_ptr< Surface > CreateGPUSurface(GrDirectContext *gr_context=nullptr) override
std::shared_ptr< IOSExternalViewEmbedder > GetSurfaceExternalViewEmbedder() const
Definition: ios_surface.mm:69
IOSSurfaceSoftware(fml::scoped_nsobject< CALayer > layer, std::shared_ptr< IOSContext > context, const std::shared_ptr< FlutterPlatformViewsController > &platform_views_controller)
ExternalViewEmbedder * GetExternalViewEmbedder() override
Gets the view embedder that controls how the Flutter layer hierarchy split into multiple chunks shoul...
bool PresentBackingStore(sk_sp< SkSurface > backing_store) override
Called by the platform when a frame has been rendered into the backing store and the platform must di...