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 // 2021.4.30 platform view adapt ohos.
5 // Copyright (c) 2021 Huawei Device Co., Ltd. All rights reserved.
6
7 #include "flutter/shell/platform/ohos/ohos_surface_software.h"
8
9 #include <memory>
10 #include <vector>
11
12 #include "flutter/fml/logging.h"
13 #include "flutter/fml/trace_event.h"
14
15 #include "display_type.h"
16
17 namespace flutter {
18
19 namespace {
20
GetSkColorType(int32_t buffer_format,SkColorType * color_type,SkAlphaType * alpha_type)21 bool GetSkColorType(int32_t buffer_format,
22 SkColorType* color_type,
23 SkAlphaType* alpha_type)
24 {
25 switch (buffer_format) {
26 case PIXEL_FMT_RGB_565:
27 *color_type = kRGB_565_SkColorType;
28 *alpha_type = kOpaque_SkAlphaType;
29 return true;
30 case PIXEL_FMT_RGBA_8888:
31 *color_type = kRGBA_8888_SkColorType;
32 *alpha_type = kPremul_SkAlphaType;
33 return true;
34 default:
35 return false;
36 }
37 return false;
38 }
39
40 } // anonymous namespace
41
OhosSurfaceSoftware()42 OhosSurfaceSoftware::OhosSurfaceSoftware()
43 {
44 GetSkColorType(PIXEL_FMT_RGBA_8888, &target_color_type_, &target_alpha_type_);
45 }
46
IsValid() const47 bool OhosSurfaceSoftware::IsValid() const
48 {
49 return true;
50 }
51
CreateGPUSurface()52 std::unique_ptr<Surface> OhosSurfaceSoftware::CreateGPUSurface()
53 {
54 if (!IsValid()) {
55 return nullptr;
56 }
57
58 auto surface = std::make_unique<GPUSurfaceSoftware>(this);
59
60 if (!surface->IsValid()) {
61 return nullptr;
62 }
63
64 return surface;
65 }
66
OnScreenSurfaceResize(const SkISize & size)67 bool OhosSurfaceSoftware::OnScreenSurfaceResize(const SkISize& size)
68 {
69 FML_LOG(INFO) << "OhosSurfaceSoftware::OnScreenSurfaceResize, software surface do noting";
70 requestConfig_.width = size.fWidth;
71 requestConfig_.height = size.fHeight;
72 return true;
73 }
74
SetPlatformWindow(const OHOS::sptr<OHOS::Rosen::Window> & window)75 void OhosSurfaceSoftware::SetPlatformWindow(const OHOS::sptr<OHOS::Rosen::Window> &window)
76 {
77 if (window == nullptr) {
78 FML_LOG(ERROR) << "OhosSurfaceSoftware::SetPlatformWindow, window is nullptr";
79 return;
80 }
81 window_ = window;
82 auto surfaceNode = window->GetSurfaceNode();
83 if (!surfaceNode) {
84 FML_LOG(ERROR) << "surface node is null";
85 }
86 surface_ = surfaceNode->GetSurface();
87 if (surface_ == nullptr) {
88 FML_LOG(ERROR) << "OhosSurfaceSoftware::SetPlatformWindow, surface_ is nullptr";
89 return;
90 }
91 requestConfig_ = {
92 .width = surface_->GetDefaultWidth(),
93 .height = surface_->GetDefaultHeight(),
94 .strideAlignment = 0x8,
95 .format = PIXEL_FMT_RGBA_8888,
96 .usage = surface_->GetDefaultUsage(),
97 };
98 // Set buffer size to 5 for enough buffer
99 surface_->SetQueueSize(5);
100 }
101
AcquireBackingStore(const SkISize & size)102 sk_sp<SkSurface> OhosSurfaceSoftware::AcquireBackingStore(
103 const SkISize& size)
104 {
105 TRACE_EVENT0("flutter", "OhosSurfaceSoftware::AcquireBackingStore");
106 if (!IsValid()) {
107 return nullptr;
108 }
109
110 if (sk_surface_ != nullptr && SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) {
111 // The old and new surface sizes are the same. Nothing to do here.
112 return sk_surface_;
113 }
114
115 SkImageInfo image_info = SkImageInfo::Make(
116 size.fWidth, size.fHeight, target_color_type_, target_alpha_type_, SkColorSpace::MakeSRGB());
117
118 sk_surface_ = SkSurface::MakeRaster(image_info);
119
120 return sk_surface_;
121 }
122
PresentBackingStore(sk_sp<SkSurface> backing_store)123 bool OhosSurfaceSoftware::PresentBackingStore(
124 sk_sp<SkSurface> backing_store)
125 {
126 TRACE_EVENT0("flutter", "OhosSurfaceSoftware::PresentBackingStore");
127 if (!IsValid() || backing_store == nullptr) {
128 return false;
129 }
130
131 FML_LOG(INFO) << "OhosSurfaceSoftware peek pixels";
132 SkPixmap pixmap;
133 if (!backing_store->peekPixels(&pixmap)) {
134 return false;
135 }
136
137 if (surface_ == nullptr) {
138 FML_LOG(ERROR) << "OhosSurfaceSoftware surface is nullptr";
139 return false;
140 }
141 int32_t pixelBase = 16;
142 int32_t convertWidth = requestConfig_.width % pixelBase == 0 ? requestConfig_.width
143 : (requestConfig_.width / pixelBase + 1) * pixelBase;
144 int32_t alignment = 8;
145 OHOS::BufferRequestConfig requestConfig = {
146 .width = convertWidth,
147 .height = requestConfig_.height,
148 .strideAlignment = alignment,
149 .format = PIXEL_FMT_RGBA_8888,
150 .usage = OHOS::BUFFER_USAGE_CPU_READ | OHOS::BUFFER_USAGE_CPU_WRITE | OHOS::BUFFER_USAGE_MEM_DMA,
151 .timeout = 0,
152 };
153 OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer;
154 int32_t releaseFence;
155
156 OHOS::SurfaceError ret = surface_->RequestBuffer(surfaceBuffer, releaseFence, requestConfig);
157 if (ret != OHOS::SURFACE_ERROR_OK || surfaceBuffer == nullptr || surfaceBuffer->GetSize() == 0) {
158 FML_LOG(ERROR) << "OhosSurfaceSoftware request surfaceBuffer fail";
159 return false;
160 }
161
162 memset(surfaceBuffer->GetVirAddr(), 0, surfaceBuffer->GetSize());
163 SurfaceDrawBuffer(requestConfig, surfaceBuffer, pixmap);
164 SurfaceFlushBuffer(surfaceBuffer);
165
166 return true;
167 }
168
SurfaceDrawBuffer(OHOS::BufferRequestConfig & requestConfig,OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer,SkPixmap & pixmap)169 void OhosSurfaceSoftware::SurfaceDrawBuffer(
170 OHOS::BufferRequestConfig& requestConfig, OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer, SkPixmap& pixmap)
171 {
172 SkColorType color_type;
173 SkAlphaType alpha_type;
174 if (GetSkColorType(requestConfig.format, &color_type, &alpha_type)) {
175 SkImageInfo native_image_info = SkImageInfo::Make(
176 requestConfig.width, requestConfig.height, color_type, alpha_type);
177
178 std::unique_ptr<SkCanvas> canvas = SkCanvas::MakeRasterDirect(
179 native_image_info, surfaceBuffer->GetVirAddr(),
180 surfaceBuffer->GetBufferHandle()->stride);
181
182 if (canvas) {
183 SkBitmap bitmap;
184 if (bitmap.installPixels(pixmap)) {
185 canvas->drawBitmapRect(bitmap, SkRect::MakeIWH(requestConfig.width, requestConfig.height), nullptr);
186 }
187 }
188 }
189 }
190
SurfaceFlushBuffer(OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer)191 void OhosSurfaceSoftware::SurfaceFlushBuffer(OHOS::sptr<OHOS::SurfaceBuffer> surfaceBuffer)
192 {
193 FML_LOG(INFO) << "OhosSurfaceSoftware flush buffer";
194 OHOS::BufferFlushConfig flushConfig = {
195 .damage = {
196 .x = 0,
197 .y = 0,
198 .w = requestConfig_.width,
199 .h = requestConfig_.height,
200 },
201 .timestamp = 0
202 };
203 surface_->FlushBuffer(surfaceBuffer, -1, flushConfig);
204 }
205
GetExternalViewEmbedder()206 ExternalViewEmbedder* OhosSurfaceSoftware::GetExternalViewEmbedder()
207 {
208 return nullptr;
209 }
210
ResourceContextMakeCurrent()211 bool OhosSurfaceSoftware::ResourceContextMakeCurrent()
212 {
213 // implement in ohos surface gl
214 return false;
215 }
216
ResourceContextClearCurrent()217 bool OhosSurfaceSoftware::ResourceContextClearCurrent()
218 {
219 // implement in ohos surface gl
220 return false;
221 }
222
TeardownOnScreenContext()223 void OhosSurfaceSoftware::TeardownOnScreenContext()
224 {
225 // implement in ohos surface gl
226 }
227
228 } // namespace flutter
229