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