• 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/android/android_surface_software.h"
6 
7 #include <memory>
8 #include <vector>
9 
10 #include "flutter/fml/logging.h"
11 #include "flutter/fml/platform/android/jni_weak_ref.h"
12 #include "flutter/fml/platform/android/scoped_java_ref.h"
13 #include "flutter/fml/trace_event.h"
14 #include "flutter/shell/platform/android/platform_view_android_jni.h"
15 
16 namespace flutter {
17 
18 namespace {
19 
GetSkColorType(int32_t buffer_format,SkColorType * color_type,SkAlphaType * alpha_type)20 bool GetSkColorType(int32_t buffer_format,
21                     SkColorType* color_type,
22                     SkAlphaType* alpha_type) {
23   switch (buffer_format) {
24     case WINDOW_FORMAT_RGB_565:
25       *color_type = kRGB_565_SkColorType;
26       *alpha_type = kOpaque_SkAlphaType;
27       return true;
28     case WINDOW_FORMAT_RGBA_8888:
29       *color_type = kRGBA_8888_SkColorType;
30       *alpha_type = kPremul_SkAlphaType;
31       return true;
32     default:
33       return false;
34   }
35 }
36 
37 }  // anonymous namespace
38 
AndroidSurfaceSoftware()39 AndroidSurfaceSoftware::AndroidSurfaceSoftware() {
40   GetSkColorType(WINDOW_FORMAT_RGBA_8888, &target_color_type_,
41                  &target_alpha_type_);
42 }
43 
44 AndroidSurfaceSoftware::~AndroidSurfaceSoftware() = default;
45 
IsValid() const46 bool AndroidSurfaceSoftware::IsValid() const {
47   return true;
48 }
49 
ResourceContextMakeCurrent()50 bool AndroidSurfaceSoftware::ResourceContextMakeCurrent() {
51   // Resource Context always not available on software backend.
52   return false;
53 }
54 
ResourceContextClearCurrent()55 bool AndroidSurfaceSoftware::ResourceContextClearCurrent() {
56   return false;
57 }
58 
CreateGPUSurface()59 std::unique_ptr<Surface> AndroidSurfaceSoftware::CreateGPUSurface() {
60   if (!IsValid()) {
61     return nullptr;
62   }
63 
64   auto surface = std::make_unique<GPUSurfaceSoftware>(this);
65 
66   if (!surface->IsValid()) {
67     return nullptr;
68   }
69 
70   return surface;
71 }
72 
AcquireBackingStore(const SkISize & size)73 sk_sp<SkSurface> AndroidSurfaceSoftware::AcquireBackingStore(
74     const SkISize& size) {
75   TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::AcquireBackingStore");
76   if (!IsValid()) {
77     return nullptr;
78   }
79 
80   if (sk_surface_ != nullptr &&
81       SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
82     // The old and new surface sizes are the same. Nothing to do here.
83     return sk_surface_;
84   }
85 
86   SkImageInfo image_info =
87       SkImageInfo::Make(size.fWidth, size.fHeight, target_color_type_,
88                         target_alpha_type_, SkColorSpace::MakeSRGB());
89 
90   sk_surface_ = SkSurface::MakeRaster(image_info);
91 
92   return sk_surface_;
93 }
94 
PresentBackingStore(sk_sp<SkSurface> backing_store)95 bool AndroidSurfaceSoftware::PresentBackingStore(
96     sk_sp<SkSurface> backing_store) {
97   TRACE_EVENT0("flutter", "AndroidSurfaceSoftware::PresentBackingStore");
98   if (!IsValid() || backing_store == nullptr) {
99     return false;
100   }
101 
102   SkPixmap pixmap;
103   if (!backing_store->peekPixels(&pixmap)) {
104     return false;
105   }
106 
107   ANativeWindow_Buffer native_buffer;
108   if (ANativeWindow_lock(native_window_->handle(), &native_buffer, nullptr)) {
109     return false;
110   }
111 
112   SkColorType color_type;
113   SkAlphaType alpha_type;
114   if (GetSkColorType(native_buffer.format, &color_type, &alpha_type)) {
115     SkImageInfo native_image_info = SkImageInfo::Make(
116         native_buffer.width, native_buffer.height, color_type, alpha_type);
117 
118     std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(
119         native_image_info, native_buffer.bits,
120         native_buffer.stride * SkColorTypeBytesPerPixel(color_type));
121 
122     if (canvas) {
123       SkBitmap bitmap;
124       if (bitmap.installPixels(pixmap)) {
125         canvas->drawBitmapRect(
126             bitmap, SkRect::MakeIWH(native_buffer.width, native_buffer.height),
127             nullptr);
128       }
129     }
130   }
131 
132   ANativeWindow_unlockAndPost(native_window_->handle());
133 
134   return true;
135 }
136 
137 // |GPUSurfaceSoftwareDelegate|
GetExternalViewEmbedder()138 ExternalViewEmbedder* AndroidSurfaceSoftware::GetExternalViewEmbedder() {
139   return nullptr;
140 }
141 
TeardownOnScreenContext()142 void AndroidSurfaceSoftware::TeardownOnScreenContext() {}
143 
OnScreenSurfaceResize(const SkISize & size) const144 bool AndroidSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size) const {
145   return true;
146 }
147 
SetNativeWindow(fml::RefPtr<AndroidNativeWindow> window)148 bool AndroidSurfaceSoftware::SetNativeWindow(
149     fml::RefPtr<AndroidNativeWindow> window) {
150   native_window_ = std::move(window);
151   if (!(native_window_ && native_window_->IsValid()))
152     return false;
153   int32_t window_format = ANativeWindow_getFormat(native_window_->handle());
154   if (window_format < 0)
155     return false;
156   if (!GetSkColorType(window_format, &target_color_type_, &target_alpha_type_))
157     return false;
158   return true;
159 }
160 
161 }  // namespace flutter
162