xref: /aosp_15_r20/external/skia/modules/jetski/src/SurfaceThread.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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  */
7 #include "modules/jetski/src/SurfaceThread.h"
8 
9 #include "tools/window/DisplayParams.h"
10 #include "tools/window/WindowContext.h"
11 #include "tools/window/android/WindowContextFactory_android.h"
12 
13 #include "include/core/SkCanvas.h"
14 #include "include/core/SkPicture.h"
15 #include "include/core/SkTypes.h"
16 
SurfaceThread()17 SurfaceThread::SurfaceThread() {
18     pipe(fPipe);
19     fRunning = true;
20     pthread_create(&fThread, nullptr, pthread_main, this);
21 }
22 
postMessage(const Message & message) const23 void SurfaceThread::postMessage(const Message& message) const {
24     write(fPipe[1], &message, sizeof(message));
25 }
26 
readMessage(Message * message) const27 void SurfaceThread::readMessage(Message* message) const {
28     read(fPipe[0], message, sizeof(Message));
29 }
30 
release()31 void SurfaceThread::release() {
32     pthread_join(fThread, nullptr);
33 }
34 
message_callback(int,int,void * data)35 int SurfaceThread::message_callback(int /* fd */, int /* events */, void* data) {
36     auto surfaceThread = (SurfaceThread*)data;
37     Message message;
38     surfaceThread->readMessage(&message);
39     // get target surface from Message
40 
41     switch (message.fType) {
42         case kInitialize: {
43             auto winctx = skwindow::MakeGLForAndroid(message.fNativeWindow,
44                                                      skwindow::DisplayParamsBuilder().build());
45             if (!winctx) {
46                 break;
47             }
48             *message.fWindowSurface = new WindowSurface(message.fNativeWindow, std::move(winctx));
49             break;
50         }
51         case kDestroy: {
52             SkDebugf("surface destroyed, shutting down thread");
53             surfaceThread->fRunning = false;
54             if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){
55                 windowSurface->release(nullptr);
56                 delete windowSurface;
57             }
58             return 0;
59         }
60         case kRenderPicture: {
61             sk_sp<SkPicture> picture(message.fPicture);
62             if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){
63                 windowSurface->getCanvas()->drawPicture(picture);
64                 windowSurface->flushAndSubmit();
65             }
66             break;
67         }
68         default: {
69             // do nothing
70         }
71     }
72 
73     return 1;  // continue receiving callbacks
74 }
75 
pthread_main(void * arg)76 void* SurfaceThread::pthread_main(void* arg) {
77     auto surfaceThread = (SurfaceThread*)arg;
78     // Looper setup
79     ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
80     ALooper_addFd(looper, surfaceThread->fPipe[0], 1, ALOOPER_EVENT_INPUT,
81                surfaceThread->message_callback, surfaceThread);
82 
83     while (surfaceThread->fRunning) {
84         int ident = ALOOPER_POLL_CALLBACK;
85         while (ident == ALOOPER_POLL_CALLBACK) {
86             ident = ALooper_pollOnce(0, nullptr, nullptr, nullptr);
87         }
88 
89         if (ident >= 0) {
90             SkDebugf("Unhandled ALooper_pollOnce ident=%d !", ident);
91         }
92     }
93     return nullptr;
94 }
95