Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Surface.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2021 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
8
9#include <android/bitmap.h>
10#include <android/log.h>
11
16
17WindowSurface::WindowSurface(ANativeWindow* win, std::unique_ptr<skwindow::WindowContext> wctx)
18 : fWindow(win)
19 , fWindowContext(std::move(wctx))
20{
21 SkASSERT(fWindow);
22 SkASSERT(fWindowContext);
23
24 fSurface = fWindowContext->getBackbufferSurface();
25}
26
28 fWindowContext.reset();
29 ANativeWindow_release(fWindow);
30}
31
33 if (fSurface) {
34 return fSurface->getCanvas();
35 }
36 return nullptr;
37}
38
41 fWindowContext->swapBuffers();
42 fSurface = fWindowContext->getBackbufferSurface();
43}
44
45// SkSurface created from being passed an android.view.Surface
46// For now, assume we are always rendering with OpenGL
47// TODO: add option of choose backing
49 : fThread(std::make_unique<SurfaceThread>()) {
50 ANativeWindow* window = ANativeWindow_fromSurface(env, surface);
51 fWidth = ANativeWindow_getWidth(window);
52 fHeight = ANativeWindow_getHeight(window);
53
55 message.fNativeWindow = window;
56 message.fWindowSurface = &fWindowSurface;
57 fThread->postMessage(message);
58}
59
62 message.fWindowSurface = &fWindowSurface;
63 fThread->postMessage(message);
64 fThread->release();
65}
66
68 return fRecorder.beginRecording(fWidth,
69 fHeight);
70}
71
74 message.fWindowSurface = &fWindowSurface;
75 message.fPicture = fRecorder.finishRecordingAsPicture().release();
76 fThread->postMessage(message);
77}
78
79namespace {
80
81class BitmapSurface final : public Surface {
82public:
83 BitmapSurface(JNIEnv* env, jobject bitmap) {
84 AndroidBitmapInfo bm_info;
85 if (AndroidBitmap_getInfo(env, bitmap, &bm_info) != ANDROID_BITMAP_RESULT_SUCCESS) {
86 return;
87 }
88
89 const auto info = SkImageInfo::Make(bm_info.width, bm_info.height,
90 color_type(bm_info.format), alpha_type(bm_info.flags));
91
92 void* pixels;
93 if (AndroidBitmap_lockPixels(env, bitmap, &pixels) != ANDROID_BITMAP_RESULT_SUCCESS) {
94 return;
95 }
96
97 fSurface = SkSurfaces::WrapPixels(info, pixels, bm_info.stride);
98 if (!fSurface) {
99 AndroidBitmap_unlockPixels(env, bitmap);
100 return;
101 }
102
103 fBitmap = env->NewGlobalRef(bitmap);
104 }
105
106private:
107 void release(JNIEnv* env) override {
108 if (fSurface) {
109 AndroidBitmap_unlockPixels(env, fBitmap);
110 fSurface.reset();
111 env->DeleteGlobalRef(fBitmap);
112 }
113 }
114
115 SkCanvas* getCanvas() override {
116 if (fSurface) {
117 return fSurface->getCanvas();
118 }
119 return nullptr;
120 }
121
122 void flushAndSubmit() override {
123 // Nothing to do.
124 }
125
126 static SkColorType color_type(int32_t format) {
127 switch (format) {
128 case ANDROID_BITMAP_FORMAT_RGBA_8888: return kRGBA_8888_SkColorType;
129 case ANDROID_BITMAP_FORMAT_RGB_565: return kRGB_565_SkColorType;
130 case ANDROID_BITMAP_FORMAT_RGBA_4444: return kARGB_4444_SkColorType;
131 case ANDROID_BITMAP_FORMAT_RGBA_F16: return kRGBA_F16_SkColorType;
132 case ANDROID_BITMAP_FORMAT_A_8: return kAlpha_8_SkColorType;
133 default: break;
134 }
135
137 }
138
139 static SkAlphaType alpha_type(int32_t flags) {
140 switch ((flags >> ANDROID_BITMAP_FLAGS_ALPHA_SHIFT) & ANDROID_BITMAP_FLAGS_ALPHA_MASK) {
141 case ANDROID_BITMAP_FLAGS_ALPHA_OPAQUE: return kOpaque_SkAlphaType;
142 case ANDROID_BITMAP_FLAGS_ALPHA_PREMUL: return kPremul_SkAlphaType;
143 case ANDROID_BITMAP_FLAGS_ALPHA_UNPREMUL: return kUnpremul_SkAlphaType;
144 default: break;
145 }
146
148 }
149
150 jobject fBitmap;
151};
152
153// *** JNI methods ***
154
155static jlong Surface_CreateBitmap(JNIEnv* env, jobject, jobject bitmap) {
156 return reinterpret_cast<jlong>(new BitmapSurface(env, bitmap));
157}
158
159static jlong Surface_CreateThreadedSurface(JNIEnv* env, jobject, jobject surface) {
160 return reinterpret_cast<jlong>(new ThreadedSurface(env, surface));
161}
162
163static jlong Surface_CreateVK(JNIEnv* env, jobject, jobject jsurface) {
164#ifdef SK_VULKAN
165 auto* win = ANativeWindow_fromSurface(env, jsurface);
166 if (!win) {
167 return 0;
168 }
169
170 // TODO: match window params?
172 auto winctx = skwindow::MakeVulkanForAndroid(win, params);
173 if (!winctx) {
174 return 0;
175 }
176
177 return reinterpret_cast<jlong>(sk_make_sp<WindowSurface>(win, std::move(winctx)).release());
178#else
179 return 0;
180#endif // SK_VULKAN
181}
182
183static jlong Surface_CreateGL(JNIEnv* env, jobject, jobject jsurface) {
184#ifdef SK_GL
185 auto* win = ANativeWindow_fromSurface(env, jsurface);
186 if (!win) {
187 return 0;
188 }
189
190 // TODO: match window params?
192 auto winctx = skwindow::MakeGLForAndroid(win, params);
193 if (!winctx) {
194 return 0;
195 }
196
197 return reinterpret_cast<jlong>(sk_make_sp<WindowSurface>(win, std::move(winctx)).release());
198#else // SK_GL
199 return 0;
200#endif
201}
202
203static void Surface_Release(JNIEnv* env, jobject, jlong native_surface) {
204 if (auto* surface = reinterpret_cast<Surface*>(native_surface)) {
205 surface->release(env);
207 }
208}
209
210static jlong Surface_GetNativeCanvas(JNIEnv* env, jobject, jlong native_surface) {
211 auto* surface = reinterpret_cast<Surface*>(native_surface);
212 return surface
213 ? reinterpret_cast<jlong>(surface->getCanvas())
214 : 0;
215}
216
217static void Surface_FlushAndSubmit(JNIEnv* env, jobject, jlong native_surface) {
218 if (auto* surface = reinterpret_cast<Surface*>(native_surface)) {
219 surface->flushAndSubmit();
220 }
221}
222
223static jint Surface_GetWidth(JNIEnv* env, jobject, jlong native_surface) {
224 const auto* surface = reinterpret_cast<Surface*>(native_surface);
225 return surface ? surface->width() : 0;
226}
227
228static jint Surface_GetHeight(JNIEnv* env, jobject, jlong native_surface) {
229 const auto* surface = reinterpret_cast<Surface*>(native_surface);
230 return surface ? surface->height() : 0;
231}
232
233static jlong Surface_MakeSnapshot(JNIEnv* env, jobject, jlong native_surface) {
234 if (const auto* surface = reinterpret_cast<Surface*>(native_surface)) {
235 auto snapshot = surface->makeImageSnapshot();
236 return reinterpret_cast<jlong>(snapshot.release());
237 }
238
239 return 0;
240}
241
242// *** End of JNI methods ***
243
244} // namespace
245
247 static const JNINativeMethod methods[] = {
248 {"nCreateBitmap" , "(Landroid/graphics/Bitmap;)J",
249 reinterpret_cast<void*>(Surface_CreateBitmap) },
250 {"nCreateThreadedSurface" , "(Landroid/view/Surface;)J",
251 reinterpret_cast<void*>(Surface_CreateThreadedSurface) },
252 {"nCreateVKSurface" , "(Landroid/view/Surface;)J",
253 reinterpret_cast<void*>(Surface_CreateVK) },
254 {"nCreateGLSurface" , "(Landroid/view/Surface;)J",
255 reinterpret_cast<void*>(Surface_CreateGL) },
256 {"nRelease" , "(J)V", reinterpret_cast<void*>(Surface_Release) },
257 {"nGetNativeCanvas" , "(J)J", reinterpret_cast<void*>(Surface_GetNativeCanvas)},
258 {"nFlushAndSubmit" , "(J)V", reinterpret_cast<void*>(Surface_FlushAndSubmit) },
259 {"nGetWidth" , "(J)I", reinterpret_cast<void*>(Surface_GetWidth) },
260 {"nGetHeight" , "(J)I", reinterpret_cast<void*>(Surface_GetHeight) },
261 {"nMakeImageSnapshot", "(J)J", reinterpret_cast<void*>(Surface_MakeSnapshot) },
262 };
263
264 const auto clazz = env->FindClass("org/skia/jetski/Surface");
265 return clazz
266 ? env->RegisterNatives(clazz, methods, std::size(methods))
267 : JNI_ERR;
268}
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition DM.cpp:213
kUnpremul_SkAlphaType
SkAlphaType
Definition SkAlphaType.h:26
@ kUnknown_SkAlphaType
uninitialized
Definition SkAlphaType.h:27
@ kOpaque_SkAlphaType
pixel is opaque
Definition SkAlphaType.h:28
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition SkAlphaType.h:29
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition SkColorType.h:23
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition SkColorType.h:21
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
static void SkSafeUnref(T *obj)
Definition SkRefCnt.h:149
@ kRenderPicture
@ kInitialize
@ kDestroy
int register_jetski_Surface(JNIEnv *env)
Definition Surface.cpp:246
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
SkCanvas * getCanvas()
Definition SkSurface.cpp:82
int height() const
Definition Surface.h:36
virtual SkCanvas * getCanvas()=0
virtual void release(JNIEnv *)=0
sk_sp< SkSurface > fSurface
Definition Surface.h:43
int width() const
Definition Surface.h:35
virtual void flushAndSubmit()=0
SkCanvas * getCanvas() override
Definition Surface.cpp:67
void release(JNIEnv *env) override
Definition Surface.cpp:60
void flushAndSubmit() override
Definition Surface.cpp:72
ThreadedSurface(JNIEnv *env, jobject surface)
Definition Surface.cpp:48
void release(JNIEnv *env) override
Definition Surface.cpp:27
void flushAndSubmit() override
Definition Surface.cpp:39
WindowSurface(ANativeWindow *win, std::unique_ptr< skwindow::WindowContext > wctx)
Definition Surface.cpp:17
SkCanvas * getCanvas() override
Definition Surface.cpp:32
T * release()
Definition SkRefCnt.h:324
const EmbeddedViewParams * params
GLFWwindow * window
Definition main.cc:45
VkSurfaceKHR surface
Definition main.cc:49
FlutterSemanticsFlag flags
uint32_t uint32_t * format
Win32Message message
SK_API sk_sp< SkSurface > WrapPixels(const SkImageInfo &imageInfo, void *pixels, size_t rowBytes, const SkSurfaceProps *surfaceProps=nullptr)
Definition __init__.py:1
SK_API void FlushAndSubmit(sk_sp< SkSurface >)
std::unique_ptr< WindowContext > MakeVulkanForAndroid(ANativeWindow *window, const DisplayParams &params)
Definition ref_ptr.h:256
uint32_t color_type
uint32_t alpha_type
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
struct ANativeWindow ANativeWindow