1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#include "modules/androidkit/src/SurfaceThread.h" 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "tools/sk_app/WindowContext.h" 10cb93a386Sopenharmony_ci#include "tools/sk_app/android/WindowContextFactory_android.h" 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 13cb93a386Sopenharmony_ci#include "include/core/SkTypes.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ciSurfaceThread::SurfaceThread() { 16cb93a386Sopenharmony_ci pipe(fPipe); 17cb93a386Sopenharmony_ci fRunning = true; 18cb93a386Sopenharmony_ci pthread_create(&fThread, nullptr, pthread_main, this); 19cb93a386Sopenharmony_ci} 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_civoid SurfaceThread::postMessage(const Message& message) const { 22cb93a386Sopenharmony_ci write(fPipe[1], &message, sizeof(message)); 23cb93a386Sopenharmony_ci} 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_civoid SurfaceThread::readMessage(Message* message) const { 26cb93a386Sopenharmony_ci read(fPipe[0], message, sizeof(Message)); 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_civoid SurfaceThread::release() { 30cb93a386Sopenharmony_ci pthread_join(fThread, nullptr); 31cb93a386Sopenharmony_ci} 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ciint SurfaceThread::message_callback(int /* fd */, int /* events */, void* data) { 34cb93a386Sopenharmony_ci auto surfaceThread = (SurfaceThread*)data; 35cb93a386Sopenharmony_ci Message message; 36cb93a386Sopenharmony_ci surfaceThread->readMessage(&message); 37cb93a386Sopenharmony_ci // get target surface from Message 38cb93a386Sopenharmony_ci 39cb93a386Sopenharmony_ci switch (message.fType) { 40cb93a386Sopenharmony_ci case kInitialize: { 41cb93a386Sopenharmony_ci sk_app::DisplayParams params; 42cb93a386Sopenharmony_ci auto winctx = sk_app::window_context_factory::MakeGLForAndroid(message.fNativeWindow, params); 43cb93a386Sopenharmony_ci if (!winctx) { 44cb93a386Sopenharmony_ci break; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci *message.fWindowSurface = new WindowSurface(message.fNativeWindow, std::move(winctx)); 47cb93a386Sopenharmony_ci break; 48cb93a386Sopenharmony_ci } 49cb93a386Sopenharmony_ci case kDestroy: { 50cb93a386Sopenharmony_ci SkDebugf("surface destroyed, shutting down thread"); 51cb93a386Sopenharmony_ci surfaceThread->fRunning = false; 52cb93a386Sopenharmony_ci if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){ 53cb93a386Sopenharmony_ci windowSurface->release(nullptr); 54cb93a386Sopenharmony_ci delete windowSurface; 55cb93a386Sopenharmony_ci } 56cb93a386Sopenharmony_ci return 0; 57cb93a386Sopenharmony_ci break; 58cb93a386Sopenharmony_ci } 59cb93a386Sopenharmony_ci case kRenderPicture: { 60cb93a386Sopenharmony_ci sk_sp<SkPicture> picture(message.fPicture); 61cb93a386Sopenharmony_ci if(auto* windowSurface = reinterpret_cast<Surface*>(*message.fWindowSurface)){ 62cb93a386Sopenharmony_ci windowSurface->getCanvas()->drawPicture(picture); 63cb93a386Sopenharmony_ci windowSurface->flushAndSubmit(); 64cb93a386Sopenharmony_ci } 65cb93a386Sopenharmony_ci break; 66cb93a386Sopenharmony_ci } 67cb93a386Sopenharmony_ci default: { 68cb93a386Sopenharmony_ci // do nothing 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci 72cb93a386Sopenharmony_ci return 1; // continue receiving callbacks 73cb93a386Sopenharmony_ci} 74cb93a386Sopenharmony_ci 75cb93a386Sopenharmony_civoid* SurfaceThread::pthread_main(void* arg) { 76cb93a386Sopenharmony_ci auto surfaceThread = (SurfaceThread*)arg; 77cb93a386Sopenharmony_ci // Looper setup 78cb93a386Sopenharmony_ci ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); 79cb93a386Sopenharmony_ci ALooper_addFd(looper, surfaceThread->fPipe[0], 1, ALOOPER_EVENT_INPUT, 80cb93a386Sopenharmony_ci surfaceThread->message_callback, surfaceThread); 81cb93a386Sopenharmony_ci 82cb93a386Sopenharmony_ci while (surfaceThread->fRunning) { 83cb93a386Sopenharmony_ci const int ident = ALooper_pollAll(0, nullptr, nullptr, nullptr); 84cb93a386Sopenharmony_ci 85cb93a386Sopenharmony_ci if (ident >= 0) { 86cb93a386Sopenharmony_ci SkDebugf("Unhandled ALooper_pollAll ident=%d !", ident); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci } 89cb93a386Sopenharmony_ci return nullptr; 90cb93a386Sopenharmony_ci} 91