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