Flutter Engine
embedder_test_backingstore_producer.cc
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 #include "flutter/shell/platform/embedder/tests/embedder_test_backingstore_producer.h"
6 
7 #include "flutter/fml/logging.h"
8 #include "include/core/SkImageInfo.h"
9 #include "include/core/SkSize.h"
10 #include "third_party/skia/include/core/SkSurface.h"
11 
12 #include <memory>
13 
14 namespace flutter {
15 namespace testing {
16 
18  sk_sp<GrDirectContext> context,
20  : context_(context),
21  type_(type)
22 #ifdef SHELL_ENABLE_METAL
23  ,
24  test_metal_context_(std::make_unique<TestMetalContext>())
25 #endif
26 {
27 }
28 
30 
32  const FlutterBackingStoreConfig* config,
33  FlutterBackingStore* renderer_out) {
34  switch (type_) {
36  return CreateSoftware(config, renderer_out);
37 #ifdef SHELL_ENABLE_GL
39  return CreateTexture(config, renderer_out);
41  return CreateFramebuffer(config, renderer_out);
42 #endif
43 #ifdef SHELL_ENABLE_METAL
45  return CreateMTLTexture(config, renderer_out);
46 #endif
47  default:
48  return false;
49  }
50 }
51 
52 bool EmbedderTestBackingStoreProducer::CreateFramebuffer(
53  const FlutterBackingStoreConfig* config,
54  FlutterBackingStore* backing_store_out) {
55 #ifdef SHELL_ENABLE_GL
56  const auto image_info =
57  SkImageInfo::MakeN32Premul(config->size.width, config->size.height);
58 
59  auto surface = SkSurface::MakeRenderTarget(
60  context_.get(), // context
61  SkBudgeted::kNo, // budgeted
62  image_info, // image info
63  1, // sample count
64  kBottomLeft_GrSurfaceOrigin, // surface origin
65  nullptr, // surface properties
66  false // mipmaps
67  );
68 
69  if (!surface) {
70  FML_LOG(ERROR) << "Could not create render target for compositor layer.";
71  return false;
72  }
73 
74  GrBackendRenderTarget render_target = surface->getBackendRenderTarget(
75  SkSurface::BackendHandleAccess::kDiscardWrite_BackendHandleAccess);
76 
77  if (!render_target.isValid()) {
78  FML_LOG(ERROR) << "Backend render target was invalid.";
79  return false;
80  }
81 
82  GrGLFramebufferInfo framebuffer_info = {};
83  if (!render_target.getGLFramebufferInfo(&framebuffer_info)) {
84  FML_LOG(ERROR) << "Could not access backend framebuffer info.";
85  return false;
86  }
87 
88  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
89  backing_store_out->user_data = surface.get();
91  backing_store_out->open_gl.framebuffer.target = framebuffer_info.fFormat;
92  backing_store_out->open_gl.framebuffer.name = framebuffer_info.fFBOID;
93  // The balancing unref is in the destruction callback.
94  surface->ref();
95  backing_store_out->open_gl.framebuffer.user_data = surface.get();
96  backing_store_out->open_gl.framebuffer.destruction_callback =
97  [](void* user_data) { reinterpret_cast<SkSurface*>(user_data)->unref(); };
98 
99  return true;
100 #else
101  return false;
102 #endif
103 }
104 
105 bool EmbedderTestBackingStoreProducer::CreateTexture(
106  const FlutterBackingStoreConfig* config,
107  FlutterBackingStore* backing_store_out) {
108 #ifdef SHELL_ENABLE_GL
109  const auto image_info =
110  SkImageInfo::MakeN32Premul(config->size.width, config->size.height);
111 
112  auto surface = SkSurface::MakeRenderTarget(
113  context_.get(), // context
114  SkBudgeted::kNo, // budgeted
115  image_info, // image info
116  1, // sample count
117  kBottomLeft_GrSurfaceOrigin, // surface origin
118  nullptr, // surface properties
119  false // mipmaps
120  );
121 
122  if (!surface) {
123  FML_LOG(ERROR) << "Could not create render target for compositor layer.";
124  return false;
125  }
126 
127  GrBackendTexture render_texture = surface->getBackendTexture(
128  SkSurface::BackendHandleAccess::kDiscardWrite_BackendHandleAccess);
129 
130  if (!render_texture.isValid()) {
131  FML_LOG(ERROR) << "Backend render texture was invalid.";
132  return false;
133  }
134 
135  GrGLTextureInfo texture_info = {};
136  if (!render_texture.getGLTextureInfo(&texture_info)) {
137  FML_LOG(ERROR) << "Could not access backend texture info.";
138  return false;
139  }
140 
141  backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
142  backing_store_out->user_data = surface.get();
143  backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeTexture;
144  backing_store_out->open_gl.texture.target = texture_info.fTarget;
145  backing_store_out->open_gl.texture.name = texture_info.fID;
146  backing_store_out->open_gl.texture.format = texture_info.fFormat;
147  // The balancing unref is in the destruction callback.
148  surface->ref();
149  backing_store_out->open_gl.texture.user_data = surface.get();
150  backing_store_out->open_gl.texture.destruction_callback =
151  [](void* user_data) { reinterpret_cast<SkSurface*>(user_data)->unref(); };
152 
153  return true;
154 #else
155  return false;
156 #endif
157 }
158 
159 bool EmbedderTestBackingStoreProducer::CreateSoftware(
160  const FlutterBackingStoreConfig* config,
161  FlutterBackingStore* backing_store_out) {
162  auto surface = SkSurface::MakeRaster(
163  SkImageInfo::MakeN32Premul(config->size.width, config->size.height));
164 
165  if (!surface) {
166  FML_LOG(ERROR)
167  << "Could not create the render target for compositor layer.";
168  return false;
169  }
170 
171  SkPixmap pixmap;
172  if (!surface->peekPixels(&pixmap)) {
173  FML_LOG(ERROR) << "Could not peek pixels of pixmap.";
174  return false;
175  }
176 
177  backing_store_out->type = kFlutterBackingStoreTypeSoftware;
178  backing_store_out->user_data = surface.get();
179  backing_store_out->software.allocation = pixmap.addr();
180  backing_store_out->software.row_bytes = pixmap.rowBytes();
181  backing_store_out->software.height = pixmap.height();
182  // The balancing unref is in the destruction callback.
183  surface->ref();
184  backing_store_out->software.user_data = surface.get();
185  backing_store_out->software.destruction_callback = [](void* user_data) {
186  reinterpret_cast<SkSurface*>(user_data)->unref();
187  };
188 
189  return true;
190 }
191 
192 bool EmbedderTestBackingStoreProducer::CreateMTLTexture(
193  const FlutterBackingStoreConfig* config,
194  FlutterBackingStore* backing_store_out) {
195 #ifdef SHELL_ENABLE_METAL
196  // TODO(gw280): Use SkSurface::MakeRenderTarget instead of generating our
197  // own MTLTexture and wrapping it.
198  auto surface_size = SkISize::Make(config->size.width, config->size.height);
199  auto texture_info = test_metal_context_->CreateMetalTexture(surface_size);
200  sk_cfp<FlutterMetalTextureHandle> texture;
201  texture.retain(texture_info.texture);
202 
203  GrMtlTextureInfo skia_texture_info;
204  skia_texture_info.fTexture = texture;
205  GrBackendTexture backend_texture(surface_size.width(), surface_size.height(),
206  GrMipmapped::kNo, skia_texture_info);
207 
208  SkSurface::TextureReleaseProc release_mtltexture = [](void* user_data) {
209  SkCFSafeRelease(user_data);
210  };
211 
212  sk_sp<SkSurface> surface = SkSurface::MakeFromBackendTexture(
213  context_.get(), backend_texture, kTopLeft_GrSurfaceOrigin, 1,
214  kBGRA_8888_SkColorType, nullptr, nullptr, release_mtltexture,
215  texture_info.texture);
216 
217  if (!surface) {
218  FML_LOG(ERROR) << "Could not create Skia surface from a Metal texture.";
219  return false;
220  }
221 
222  backing_store_out->type = kFlutterBackingStoreTypeMetal;
223  backing_store_out->user_data = surface.get();
224  backing_store_out->metal.texture.texture = texture_info.texture;
225  // The balancing unref is in the destruction callback.
226  surface->ref();
227  backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
228  backing_store_out->metal.texture.user_data = surface.get();
229  backing_store_out->metal.texture.destruction_callback = [](void* user_data) {
230  reinterpret_cast<SkSurface*>(user_data)->unref();
231  };
232 
233  return true;
234 #else
235  return false;
236 #endif
237 }
238 
239 } // namespace testing
240 } // namespace flutter
Specified an software allocation for Flutter to render into using the CPU.
Definition: embedder.h:1048
FlutterOpenGLFramebuffer framebuffer
Definition: embedder.h:960
size_t struct_size
The size of this struct. Must be sizeof(FlutterMetalBackingStore).
Definition: embedder.h:983
void * user_data
Definition: ref_ptr.h:255
Specifies a Metal backing store. This is backed by a Metal texture.
Definition: embedder.h:1050
#define FML_LOG(severity)
Definition: logging.h:65
EmbedderTestBackingStoreProducer(sk_sp< GrDirectContext > context, RenderTargetType type)
VoidCallback destruction_callback
Definition: embedder.h:978
FlutterOpenGLTargetType type
Definition: embedder.h:954
FlutterMetalTexture texture
Definition: embedder.h:988
VoidCallback destruction_callback
Definition: embedder.h:299
VoidCallback destruction_callback
Definition: embedder.h:509
GdkEventType type
Definition: fl_view.cc:80
FlutterSoftwareBackingStore software
The description of the software backing store.
Definition: embedder.h:1069
VoidCallback destruction_callback
Definition: embedder.h:274
size_t row_bytes
The number of bytes in a single row of the allocation.
Definition: embedder.h:969
FlutterOpenGLBackingStore open_gl
The description of the OpenGL backing store.
Definition: embedder.h:1067
double width
Definition: embedder.h:320
size_t height
The number of rows in the allocation.
Definition: embedder.h:971
FlutterBackingStoreType type
Specifies the type of backing store.
Definition: embedder.h:1061
FlutterMetalTextureHandle texture
Definition: embedder.h:502
double height
Definition: embedder.h:321
FlutterMetalBackingStore metal
Definition: embedder.h:1071
uint32_t name
The name of the texture.
Definition: embedder.h:267
FlutterSize size
The size of the render target the engine expects to render into.
Definition: embedder.h:1079
FlTexture * texture
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition: embedder.h:295
void * user_data
User data to be returned on the invocation of the destruction callback.
Definition: embedder.h:271
uint32_t format
The texture format (example GL_RGBA8).
Definition: embedder.h:269
uint32_t name
The name of the framebuffer.
Definition: embedder.h:292
FlutterOpenGLTexture texture
A texture for Flutter to render into.
Definition: embedder.h:957
bool Create(const FlutterBackingStoreConfig *config, FlutterBackingStore *renderer_out)