• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2016 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 #include "RendererImpl.h"
15 
16 #include <assert.h>
17 
18 #include <algorithm>
19 #include <utility>
20 #include <variant>
21 
22 #include "FrameBuffer.h"
23 #include "GraphicsDriverLock.h"
24 #include "RenderChannelImpl.h"
25 #include "RenderThread.h"
26 #include "aemu/base/system/System.h"
27 #include "aemu/base/threads/WorkerThread.h"
28 #include "host-common/logging.h"
29 #include "snapshot/common.h"
30 
31 #if GFXSTREAM_ENABLE_HOST_GLES
32 #include "gl/EmulatedEglFenceSync.h"
33 #endif
34 
35 namespace gfxstream {
36 
37 // kUseSubwindowThread is used to determine whether the RenderWindow should use
38 // a separate thread to manage its subwindow GL/GLES context.
39 // For now, this feature is disabled entirely for the following
40 // reasons:
41 //
42 // - It must be disabled on Windows at all times, otherwise the main window
43 //   becomes unresponsive after a few seconds of user interaction (e.g. trying
44 //   to move it over the desktop). Probably due to the subtle issues around
45 //   input on this platform (input-queue is global, message-queue is
46 //   per-thread). Also, this messes considerably the display of the
47 //   main window when running the executable under Wine.
48 //
49 // - On Linux/XGL and OSX/Cocoa, this used to be necessary to avoid corruption
50 //   issues with the GL state of the main window when using the SDL UI.
51 //   After the switch to Qt, this is no longer necessary and may actually cause
52 //   undesired interactions between the UI thread and the RenderWindow thread:
53 //   for example, in a multi-monitor setup the context might be recreated when
54 //   dragging the window between monitors, triggering a Qt-specific callback
55 //   in the context of RenderWindow thread, which will become blocked on the UI
56 //   thread, which may in turn be blocked on something else.
57 static const bool kUseSubwindowThread = false;
58 
59 // This object manages the cleanup of guest process resources when the process
60 // exits. It runs the cleanup in a separate thread to never block the main
61 // render thread for a low-priority task.
62 class RendererImpl::ProcessCleanupThread {
63 public:
ProcessCleanupThread()64     ProcessCleanupThread()
65         : mCleanupWorker([](Cmd cmd) {
66             using android::base::WorkerProcessingResult;
67             struct {
68                 WorkerProcessingResult operator()(CleanProcessResources resources) {
69                     FrameBuffer::getFB()->cleanupProcGLObjects(resources.puid);
70                     // resources.resource are destroyed automatically when going out of the scope.
71                     return WorkerProcessingResult::Continue;
72                 }
73                 WorkerProcessingResult operator()(Exit) {
74                     return WorkerProcessingResult::Stop;
75                 }
76             } visitor;
77             return std::visit(visitor, std::move(cmd));
78           }) {
79         mCleanupWorker.start();
80     }
81 
~ProcessCleanupThread()82     ~ProcessCleanupThread() {
83         mCleanupWorker.enqueue(Exit{});
84     }
85 
cleanup(uint64_t processId,std::unique_ptr<ProcessResources> resource)86     void cleanup(uint64_t processId, std::unique_ptr<ProcessResources> resource) {
87         mCleanupWorker.enqueue(CleanProcessResources{
88             .puid = processId,
89             .resource = std::move(resource),
90         });
91     }
92 
stop()93     void stop() {
94         mCleanupWorker.enqueue(Exit{});
95         mCleanupWorker.join();
96     }
97 
waitForCleanup()98     void waitForCleanup() {
99         mCleanupWorker.waitQueuedItems();
100     }
101 
102 private:
103     struct CleanProcessResources {
104         uint64_t puid;
105         std::unique_ptr<ProcessResources> resource;
106     };
107     struct Exit {};
108     using Cmd = std::variant<CleanProcessResources, Exit>;
109     DISALLOW_COPY_AND_ASSIGN(ProcessCleanupThread);
110 
111     android::base::WorkerThread<Cmd> mCleanupWorker;
112 };
113 
RendererImpl()114 RendererImpl::RendererImpl() {
115     mCleanupThread.reset(new ProcessCleanupThread());
116 }
117 
~RendererImpl()118 RendererImpl::~RendererImpl() {
119     stop(true);
120     // We can't finish until the loader render thread has
121     // completed else can get a crash at the end of the destructor.
122     if (mLoaderRenderThread) {
123         mLoaderRenderThread->wait();
124     }
125     mRenderWindow.reset();
126 }
127 
initialize(int width,int height,gfxstream::host::FeatureSet features,bool useSubWindow,bool egl2egl)128 bool RendererImpl::initialize(int width, int height, gfxstream::host::FeatureSet features,
129                               bool useSubWindow, bool egl2egl) {
130 #ifdef CONFIG_AEMU
131     if (android::base::getEnvironmentVariable("ANDROID_EMUGL_VERBOSE") == "1") {
132         set_gfxstream_enable_verbose_logs();
133     }
134     if (android::base::getEnvironmentVariable("ANDROID_EMUGL_LOG_COLORS") == "1") {
135         set_gfxstream_enable_log_colors();
136     }
137 #endif
138 
139     if (mRenderWindow) {
140         return false;
141     }
142 
143     std::unique_ptr<RenderWindow> renderWindow(new RenderWindow(
144             width, height, features, kUseSubwindowThread, useSubWindow, egl2egl));
145     if (!renderWindow) {
146         ERR("Could not create rendering window class\n");
147         GL_LOG("Could not create rendering window class");
148         return false;
149     }
150     if (!renderWindow->isValid()) {
151         ERR("Could not initialize emulated framebuffer\n");
152         return false;
153     }
154 
155     mRenderWindow = std::move(renderWindow);
156     GL_LOG("OpenGL renderer initialized successfully");
157 
158     // This render thread won't do anything but will only preload resources
159     // for the real threads to start faster.
160     mLoaderRenderThread.reset(new RenderThread(nullptr));
161     mLoaderRenderThread->start();
162 
163     return true;
164 }
165 
stop(bool wait)166 void RendererImpl::stop(bool wait) {
167     android::base::AutoLock lock(mChannelsLock);
168     mStopped = true;
169     auto channels = std::move(mChannels);
170     lock.unlock();
171 
172     if (const auto fb = FrameBuffer::getFB()) {
173         fb->setShuttingDown();
174     }
175     for (const auto& c : channels) {
176         c->stopFromHost();
177     }
178     // We're stopping the renderer, so there's no need to clean up resources
179     // of some pending processes: we'll destroy everything soon.
180     mCleanupThread->stop();
181 
182     mStoppedChannels.insert(mStoppedChannels.end(),
183                             std::make_move_iterator(channels.begin()),
184                             std::make_move_iterator(channels.end()));
185 
186     // Each render channel is referenced in the corresponing pipe object, so
187     // even if we clear the |channels| vector they could still be alive
188     // for a while. This means we need to make sure to wait for render thread
189     // exit explicitly.
190     for (const auto& c : mStoppedChannels) {
191         c->renderThread()->waitForFinished();
192         {
193             android::base::AutoLock driverLock(*graphicsDriverLock());
194             c->renderThread()->sendExitSignal();
195             c->renderThread()->wait();
196         }
197     }
198 
199     if (!wait) {
200         return;
201     }
202 
203     mCleanupThread->waitForCleanup();
204     mStoppedChannels.clear();
205 }
206 
finish()207 void RendererImpl::finish() {
208     {
209         android::base::AutoLock lock(mChannelsLock);
210         mRenderWindow->setPaused(true);
211     }
212     cleanupRenderThreads();
213     {
214         android::base::AutoLock lock(mChannelsLock);
215         mRenderWindow->setPaused(false);
216     }
217 }
218 
cleanupRenderThreads()219 void RendererImpl::cleanupRenderThreads() {
220     android::base::AutoLock lock(mChannelsLock);
221     const auto channels = std::move(mChannels);
222     assert(mChannels.empty());
223     lock.unlock();
224     for (const auto& c : channels) {
225         // Please DO NOT notify the guest about this event (DO NOT call
226         // stopFromHost() ), because this is used to kill old threads when
227         // loading from a snapshot, and the newly loaded guest should not
228         // be notified for those behavior.
229         c->stop();
230     }
231     for (const auto& c : channels) {
232         c->renderThread()->waitForFinished();
233         {
234             android::base::AutoLock driverLock(*graphicsDriverLock());
235             c->renderThread()->sendExitSignal();
236             c->renderThread()->wait();
237         }
238     }
239 }
240 
waitForProcessCleanup()241 void RendererImpl::waitForProcessCleanup() {
242     mCleanupThread->waitForCleanup();
243     // Recreate it to make sure we've started from scratch and that we've
244     // finished all in-progress cleanups as well.
245     mCleanupThread.reset(new ProcessCleanupThread());
246 }
247 
createRenderChannel(android::base::Stream * loadStream,uint32_t virtioGpuContextId)248 RenderChannelPtr RendererImpl::createRenderChannel(
249         android::base::Stream* loadStream, uint32_t virtioGpuContextId) {
250     const auto channel =
251         std::make_shared<RenderChannelImpl>(loadStream, virtioGpuContextId);
252     {
253         android::base::AutoLock lock(mChannelsLock);
254 
255         if (mStopped) {
256             return nullptr;
257         }
258 
259         // Clean up the stopped channels.
260         mChannels.erase(
261                 std::remove_if(mChannels.begin(), mChannels.end(),
262                                [](const std::shared_ptr<RenderChannelImpl>& c) {
263                                    return c->renderThread()->isFinished();
264                                }),
265                 mChannels.end());
266         mChannels.emplace_back(channel);
267 
268         // Take the time to check if our loader thread is done as well.
269         if (mLoaderRenderThread && mLoaderRenderThread->isFinished()) {
270             mLoaderRenderThread->wait();
271             mLoaderRenderThread.reset();
272         }
273 
274         GL_LOG("Started new RenderThread (total %" PRIu64 ") @%p",
275                static_cast<uint64_t>(mChannels.size()), channel->renderThread());
276     }
277 
278     return channel;
279 }
280 
addListener(FrameBufferChangeEventListener * listener)281 void RendererImpl::addListener(FrameBufferChangeEventListener* listener) {
282     mRenderWindow->addListener(listener);
283 }
284 
removeListener(FrameBufferChangeEventListener * listener)285 void RendererImpl::removeListener(FrameBufferChangeEventListener* listener) {
286     mRenderWindow->removeListener(listener);
287 }
288 
addressSpaceGraphicsConsumerCreate(struct asg_context context,android::base::Stream * loadStream,android::emulation::asg::ConsumerCallbacks callbacks,uint32_t contextId,uint32_t capsetId,std::optional<std::string> nameOpt)289 void* RendererImpl::addressSpaceGraphicsConsumerCreate(
290     struct asg_context context,
291     android::base::Stream* loadStream,
292     android::emulation::asg::ConsumerCallbacks callbacks,
293     uint32_t contextId, uint32_t capsetId,
294     std::optional<std::string> nameOpt) {
295     auto thread = new RenderThread(context, loadStream, callbacks, contextId,
296                                    capsetId, std::move(nameOpt));
297     thread->start();
298     android::base::AutoLock lock(mAddressSpaceRenderThreadLock);
299     mAddressSpaceRenderThreads.emplace(thread);
300     return (void*)thread;
301 }
302 
addressSpaceGraphicsConsumerDestroy(void * consumer)303 void RendererImpl::addressSpaceGraphicsConsumerDestroy(void* consumer) {
304     RenderThread* thread = (RenderThread*)consumer;
305     {
306         android::base::AutoLock lock(mAddressSpaceRenderThreadLock);
307         mAddressSpaceRenderThreads.erase(thread);
308     }
309 
310     thread->waitForFinished();
311     {
312         android::base::AutoLock driverLock(*graphicsDriverLock());
313         thread->sendExitSignal();
314         thread->wait();
315     }
316     delete thread;
317 }
318 
addressSpaceGraphicsConsumerPreSave(void * consumer)319 void RendererImpl::addressSpaceGraphicsConsumerPreSave(void* consumer) {
320     RenderThread* thread = (RenderThread*)consumer;
321     thread->pausePreSnapshot();
322 }
323 
addressSpaceGraphicsConsumerSave(void * consumer,android::base::Stream * stream)324 void RendererImpl::addressSpaceGraphicsConsumerSave(void* consumer, android::base::Stream* stream) {
325     RenderThread* thread = (RenderThread*)consumer;
326     thread->save(stream);
327 }
328 
addressSpaceGraphicsConsumerPostSave(void * consumer)329 void RendererImpl::addressSpaceGraphicsConsumerPostSave(void* consumer) {
330     RenderThread* thread = (RenderThread*)consumer;
331     thread->resume();
332 }
333 
addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(void * consumer)334 void RendererImpl::addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(void* consumer) {
335     RenderThread* thread = (RenderThread*)consumer;
336     mAdditionalPostLoadRenderThreads.push_back(thread);
337 }
338 
pauseAllPreSave()339 void RendererImpl::pauseAllPreSave() {
340     {
341         android::base::AutoLock lock(mChannelsLock);
342         if (mStopped) {
343             return;
344         }
345         for (const auto& c : mChannels) {
346             c->renderThread()->pausePreSnapshot();
347         }
348     }
349     {
350         android::base::AutoLock lock(mAddressSpaceRenderThreadLock);
351         for (const auto& thread : mAddressSpaceRenderThreads) {
352             thread->pausePreSnapshot();
353         }
354     }
355     waitForProcessCleanup();
356 }
357 
resumeAll()358 void RendererImpl::resumeAll() {
359     {
360         android::base::AutoLock lock(mAddressSpaceRenderThreadLock);
361         for (const auto t : mAdditionalPostLoadRenderThreads) {
362             t->resume();
363         }
364     }
365     {
366         android::base::AutoLock lock(mChannelsLock);
367         if (mStopped) {
368             return;
369         }
370         for (const auto& c : mChannels) {
371             c->renderThread()->resume();
372         }
373         for (const auto& thread : mAddressSpaceRenderThreads) {
374             thread->resume();
375         }
376         mAdditionalPostLoadRenderThreads.clear();
377     }
378 
379     repaintOpenGLDisplay();
380 }
381 
save(android::base::Stream * stream,const android::snapshot::ITextureSaverPtr & textureSaver)382 void RendererImpl::save(android::base::Stream* stream,
383                         const android::snapshot::ITextureSaverPtr& textureSaver) {
384     stream->putByte(mStopped);
385     if (mStopped) {
386         return;
387     }
388     auto fb = FrameBuffer::getFB();
389     assert(fb);
390     fb->onSave(stream, textureSaver);
391 }
392 
load(android::base::Stream * stream,const android::snapshot::ITextureLoaderPtr & textureLoader)393 bool RendererImpl::load(android::base::Stream* stream,
394                         const android::snapshot::ITextureLoaderPtr& textureLoader) {
395 
396 #ifdef SNAPSHOT_PROFILE
397     android::base::System::Duration startTime =
398             android::base::System::get()->getUnixTimeUs();
399 #endif
400     waitForProcessCleanup();
401 #ifdef SNAPSHOT_PROFILE
402     printf("Previous session cleanup time: %lld ms\n",
403            (long long)(android::base::System::get()
404                                ->getUnixTimeUs() -
405                        startTime) /
406                    1000);
407 #endif
408 
409     mStopped = stream->getByte();
410     if (mStopped) {
411         return true;
412     }
413     auto fb = FrameBuffer::getFB();
414     assert(fb);
415     return fb->onLoad(stream, textureLoader);
416 }
417 
fillGLESUsages(android_studio::EmulatorGLESUsages * usages)418 void RendererImpl::fillGLESUsages(android_studio::EmulatorGLESUsages* usages) {
419     auto fb = FrameBuffer::getFB();
420 #if GFXSTREAM_ENABLE_HOST_GLES
421     if (fb) fb->fillGLESUsages(usages);
422 #endif
423 }
424 
getScreenshot(unsigned int nChannels,unsigned int * width,unsigned int * height,uint8_t * pixels,size_t * cPixels,int displayId=0,int desiredWidth=0,int desiredHeight=0,int desiredRotation=0,Rect rect={{0, 0}, {0, 0}})425 int RendererImpl::getScreenshot(unsigned int nChannels, unsigned int* width, unsigned int* height,
426                                 uint8_t* pixels, size_t* cPixels, int displayId = 0,
427                                 int desiredWidth = 0, int desiredHeight = 0,
428                                 int desiredRotation = 0, Rect rect = {{0, 0}, {0, 0}}) {
429     auto fb = FrameBuffer::getFB();
430     if (fb) {
431         return fb->getScreenshot(nChannels, width, height, pixels, cPixels,
432                                  displayId, desiredWidth, desiredHeight,
433                                  desiredRotation, rect);
434     }
435     *cPixels = 0;
436     return -1;
437 }
438 
setMultiDisplay(uint32_t id,int32_t x,int32_t y,uint32_t w,uint32_t h,uint32_t dpi,bool add)439 void RendererImpl::setMultiDisplay(uint32_t id,
440                                    int32_t x,
441                                    int32_t y,
442                                    uint32_t w,
443                                    uint32_t h,
444                                    uint32_t dpi,
445                                    bool add) {
446     auto fb = FrameBuffer::getFB();
447     if (fb) {
448         if (add) {
449             fb->createDisplay(&id);
450             fb->setDisplayPose(id, x, y, w, h, dpi);
451         } else {
452             fb->destroyDisplay(id);
453         }
454     }
455 }
456 
setMultiDisplayColorBuffer(uint32_t id,uint32_t cb)457 void RendererImpl::setMultiDisplayColorBuffer(uint32_t id, uint32_t cb) {
458     auto fb = FrameBuffer::getFB();
459     if (fb) {
460         fb->setDisplayColorBuffer(id, cb);
461     }
462 }
463 
getHardwareStrings()464 RendererImpl::HardwareStrings RendererImpl::getHardwareStrings() {
465     assert(mRenderWindow);
466 
467     const char* vendor = nullptr;
468     const char* renderer = nullptr;
469     const char* version = nullptr;
470     if (!mRenderWindow->getHardwareStrings(&vendor, &renderer, &version)) {
471         return {};
472     }
473     HardwareStrings res;
474     res.vendor = vendor ? vendor : "";
475     res.renderer = renderer ? renderer : "";
476     res.version = version ? version : "";
477     return res;
478 }
479 
setPostCallback(RendererImpl::OnPostCallback onPost,void * context,bool useBgraReadback,uint32_t displayId)480 void RendererImpl::setPostCallback(RendererImpl::OnPostCallback onPost,
481                                    void* context,
482                                    bool useBgraReadback,
483                                    uint32_t displayId) {
484     assert(mRenderWindow);
485     mRenderWindow->setPostCallback(onPost, context, displayId, useBgraReadback);
486 }
487 
asyncReadbackSupported()488 bool RendererImpl::asyncReadbackSupported() {
489     assert(mRenderWindow);
490     return mRenderWindow->asyncReadbackSupported();
491 }
492 
493 RendererImpl::ReadPixelsCallback
getReadPixelsCallback()494 RendererImpl::getReadPixelsCallback() {
495     assert(mRenderWindow);
496     return mRenderWindow->getReadPixelsCallback();
497 }
498 
499 RendererImpl::FlushReadPixelPipeline
getFlushReadPixelPipeline()500 RendererImpl::getFlushReadPixelPipeline() {
501     assert(mRenderWindow);
502     return mRenderWindow->getFlushReadPixelPipeline();
503 }
504 
showOpenGLSubwindow(FBNativeWindowType window,int wx,int wy,int ww,int wh,int fbw,int fbh,float dpr,float zRot,bool deleteExisting,bool hideWindow)505 bool RendererImpl::showOpenGLSubwindow(FBNativeWindowType window,
506                                        int wx,
507                                        int wy,
508                                        int ww,
509                                        int wh,
510                                        int fbw,
511                                        int fbh,
512                                        float dpr,
513                                        float zRot,
514                                        bool deleteExisting,
515                                        bool hideWindow) {
516     assert(mRenderWindow);
517     return mRenderWindow->setupSubWindow(window, wx, wy, ww, wh, fbw, fbh, dpr,
518                                          zRot, deleteExisting, hideWindow);
519 }
520 
destroyOpenGLSubwindow()521 bool RendererImpl::destroyOpenGLSubwindow() {
522     assert(mRenderWindow);
523     return mRenderWindow->removeSubWindow();
524 }
525 
setOpenGLDisplayRotation(float zRot)526 void RendererImpl::setOpenGLDisplayRotation(float zRot) {
527     assert(mRenderWindow);
528     mRenderWindow->setRotation(zRot);
529 }
530 
setOpenGLDisplayTranslation(float px,float py)531 void RendererImpl::setOpenGLDisplayTranslation(float px, float py) {
532     assert(mRenderWindow);
533     mRenderWindow->setTranslation(px, py);
534 }
535 
repaintOpenGLDisplay()536 void RendererImpl::repaintOpenGLDisplay() {
537     assert(mRenderWindow);
538     mRenderWindow->repaint();
539 }
540 
hasGuestPostedAFrame()541 bool RendererImpl::hasGuestPostedAFrame() {
542     if (mRenderWindow) {
543         return mRenderWindow->hasGuestPostedAFrame();
544     }
545     return false;
546 }
547 
resetGuestPostedAFrame()548 void RendererImpl::resetGuestPostedAFrame() {
549     if (mRenderWindow) {
550         mRenderWindow->resetGuestPostedAFrame();
551     }
552 }
553 
setScreenMask(int width,int height,const unsigned char * rgbaData)554 void RendererImpl::setScreenMask(int width, int height, const unsigned char* rgbaData) {
555     assert(mRenderWindow);
556     mRenderWindow->setScreenMask(width, height, rgbaData);
557 }
558 
onGuestGraphicsProcessCreate(uint64_t puid)559 void RendererImpl::onGuestGraphicsProcessCreate(uint64_t puid) {
560     FrameBuffer::getFB()->createGraphicsProcessResources(puid);
561 }
562 
cleanupProcGLObjects(uint64_t puid)563 void RendererImpl::cleanupProcGLObjects(uint64_t puid) {
564     std::unique_ptr<ProcessResources> resource =
565         FrameBuffer::getFB()->removeGraphicsProcessResources(puid);
566     mCleanupThread->cleanup(puid, std::move(resource));
567 }
568 
569 static struct AndroidVirtioGpuOps sVirtioGpuOps = {
570     .create_buffer_with_handle =
__anona3fc7b450402(uint64_t size, uint32_t handle) 571         [](uint64_t size, uint32_t handle) {
572             FrameBuffer::getFB()->createBufferWithResourceHandle(size, handle);
573         },
574     .create_color_buffer_with_handle =
575         [](uint32_t width, uint32_t height, uint32_t format, uint32_t fwkFormat, uint32_t handle,
__anona3fc7b450502(uint32_t width, uint32_t height, uint32_t format, uint32_t fwkFormat, uint32_t handle, bool linear) 576            bool linear) {
577             FrameBuffer::getFB()->createColorBufferWithResourceHandle(
578                 width, height, (GLenum)format, (FrameworkFormat)fwkFormat, handle, linear);
579         },
__anona3fc7b450602(uint32_t handle) 580     .open_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->openColorBuffer(handle); },
__anona3fc7b450702(uint32_t handle) 581     .close_buffer = [](uint32_t handle) { FrameBuffer::getFB()->closeBuffer(handle); },
__anona3fc7b450802(uint32_t handle) 582     .close_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->closeColorBuffer(handle); },
583     .update_buffer =
__anona3fc7b450902(uint32_t handle, uint64_t offset, uint64_t size, void* bytes) 584         [](uint32_t handle, uint64_t offset, uint64_t size, void* bytes) {
585             FrameBuffer::getFB()->updateBuffer(handle, offset, size, bytes);
586         },
587     .update_color_buffer =
588         [](uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type,
__anona3fc7b450a02(uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type, void* pixels) 589            void* pixels) {
590             FrameBuffer::getFB()->updateColorBuffer(handle, x, y, width, height, format, type,
591                                                     pixels);
592         },
593     .read_buffer =
__anona3fc7b450b02(uint32_t handle, uint64_t offset, uint64_t size, void* bytes) 594         [](uint32_t handle, uint64_t offset, uint64_t size, void* bytes) {
595             FrameBuffer::getFB()->readBuffer(handle, offset, size, bytes);
596         },
597     .read_color_buffer =
598         [](uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type,
__anona3fc7b450c02(uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type, void* pixels) 599            void* pixels) {
600             FrameBuffer::getFB()->readColorBuffer(handle, x, y, width, height, format, type,
601                                                   pixels);
602         },
603     .read_color_buffer2 =
604         [](uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type,
__anona3fc7b450d02(uint32_t handle, int x, int y, int width, int height, uint32_t format, uint32_t type, void* pixels, uint64_t pixels_size) 605            void* pixels, uint64_t pixels_size) {
606             FrameBuffer::getFB()->readColorBuffer(handle, x, y, width, height, format, type,
607                                                   pixels, pixels_size);
608         },
609     .read_color_buffer_yuv =
610         [](uint32_t handle, int x, int y, int width, int height, void* pixels,
__anona3fc7b450e02(uint32_t handle, int x, int y, int width, int height, void* pixels, uint32_t pixels_size) 611            uint32_t pixels_size) {
612             FrameBuffer::getFB()->readColorBufferYUV(handle, x, y, width, height, pixels,
613                                                      pixels_size);
614         },
__anona3fc7b450f02(uint32_t handle) 615     .post_color_buffer = [](uint32_t handle) { FrameBuffer::getFB()->post(handle); },
616     .async_post_color_buffer =
__anona3fc7b451002(uint32_t handle, CpuCompletionCallback cb) 617         [](uint32_t handle, CpuCompletionCallback cb) {
618             FrameBuffer::getFB()->postWithCallback(handle, cb);
619         },
__anona3fc7b451102() 620     .repost = []() { FrameBuffer::getFB()->repost(); },
621 #if GFXSTREAM_ENABLE_HOST_GLES
622     .create_yuv_textures =
__anona3fc7b451202(uint32_t type, uint32_t count, int width, int height, uint32_t* output) 623         [](uint32_t type, uint32_t count, int width, int height, uint32_t* output) {
624             FrameBuffer::getFB()->createYUVTextures(type, count, width, height, output);
625         },
626     .destroy_yuv_textures =
__anona3fc7b451302(uint32_t type, uint32_t count, uint32_t* textures) 627         [](uint32_t type, uint32_t count, uint32_t* textures) {
628             FrameBuffer::getFB()->destroyYUVTextures(type, count, textures);
629         },
630     .update_yuv_textures =
__anona3fc7b451402(uint32_t type, uint32_t* textures, void* privData, void* func) 631         [](uint32_t type, uint32_t* textures, void* privData, void* func) {
632             FrameBuffer::getFB()->updateYUVTextures(type, textures, privData, func);
633         },
634     .swap_textures_and_update_color_buffer =
635         [](uint32_t colorbufferhandle, int x, int y, int width, int height, uint32_t format,
__anona3fc7b451502(uint32_t colorbufferhandle, int x, int y, int width, int height, uint32_t format, uint32_t type, uint32_t texture_type, uint32_t* textures, void* metadata) 636            uint32_t type, uint32_t texture_type, uint32_t* textures, void* metadata) {
637             FrameBuffer::getFB()->swapTexturesAndUpdateColorBuffer(
638                 colorbufferhandle, x, y, width, height, format, type, texture_type, textures);
639         },
640 #endif
641     .get_last_posted_color_buffer =
__anona3fc7b451602() 642         []() { return FrameBuffer::getFB()->getLastPostedColorBuffer(); },
643 #if GFXSTREAM_ENABLE_HOST_GLES
644     .bind_color_buffer_to_texture =
__anona3fc7b451702(uint32_t handle) 645         [](uint32_t handle) { FrameBuffer::getFB()->bindColorBufferToTexture2(handle); },
__anona3fc7b451802() 646     .get_global_egl_context = []() { return FrameBuffer::getFB()->getGlobalEGLContext(); },
647 #endif
648     .set_guest_managed_color_buffer_lifetime =
__anona3fc7b451902(bool guestManaged) 649         [](bool guestManaged) {
650             FrameBuffer::getFB()->setGuestManagedColorBufferLifetime(guestManaged);
651         },
652 #if GFXSTREAM_ENABLE_HOST_GLES
653     .async_wait_for_gpu_with_cb =
__anona3fc7b451a02(uint64_t eglsync, FenceCompletionCallback cb) 654         [](uint64_t eglsync, FenceCompletionCallback cb) {
655             FrameBuffer::getFB()->asyncWaitForGpuWithCb(eglsync, cb);
656         },
657 #endif
658     .async_wait_for_gpu_vulkan_with_cb =
__anona3fc7b451b02(uint64_t device, uint64_t fence, FenceCompletionCallback cb) 659         [](uint64_t device, uint64_t fence, FenceCompletionCallback cb) {
660             FrameBuffer::getFB()->asyncWaitForGpuVulkanWithCb(device, fence, cb);
661         },
662     .async_wait_for_gpu_vulkan_qsri_with_cb =
__anona3fc7b451c02(uint64_t image, FenceCompletionCallback cb) 663         [](uint64_t image, FenceCompletionCallback cb) {
664             FrameBuffer::getFB()->asyncWaitForGpuVulkanQsriWithCb(image, cb);
665         },
666     .update_color_buffer_from_framework_format =
667         [](uint32_t handle, int x, int y, int width, int height, uint32_t fwkFormat,
__anona3fc7b451d02(uint32_t handle, int x, int y, int width, int height, uint32_t fwkFormat, uint32_t format, uint32_t type, void* pixels, void* pMetadata) 668            uint32_t format, uint32_t type, void* pixels, void* pMetadata) {
669             FrameBuffer::getFB()->updateColorBufferFromFrameworkFormat(
670                 handle, x, y, width, height, (FrameworkFormat)fwkFormat, format, type, pixels,
671                 pMetadata);
672         },
673 };
674 
getVirtioGpuOps()675 struct AndroidVirtioGpuOps* RendererImpl::getVirtioGpuOps() {
676     return &sVirtioGpuOps;
677 }
678 
snapshotOperationCallback(int op,int stage)679 void RendererImpl::snapshotOperationCallback(int op, int stage) {
680     using namespace android::snapshot;
681     switch (op) {
682         case SNAPSHOTTER_OPERATION_LOAD:
683             if (stage == SNAPSHOTTER_STAGE_START) {
684 #ifdef SNAPSHOT_PROFILE
685              android::base::System::Duration startTime =
686                      android::base::System::get()->getUnixTimeUs();
687 #endif
688                 mRenderWindow->setPaused(true);
689                 cleanupRenderThreads();
690 #ifdef SNAPSHOT_PROFILE
691                 printf("Previous session suspend time: %lld ms\n",
692                        (long long)(android::base::System::get()
693                                            ->getUnixTimeUs() -
694                                    startTime) /
695                                1000);
696 #endif
697             }
698             if (stage == SNAPSHOTTER_STAGE_END) {
699                 mRenderWindow->setPaused(false);
700             }
701             break;
702         default:
703             break;
704     }
705 }
706 
setVsyncHz(int vsyncHz)707 void RendererImpl::setVsyncHz(int vsyncHz) {
708     if (mRenderWindow) {
709         mRenderWindow->setVsyncHz(vsyncHz);
710     }
711 }
712 
setDisplayConfigs(int configId,int w,int h,int dpiX,int dpiY)713 void RendererImpl::setDisplayConfigs(int configId, int w, int h,
714                                      int dpiX, int dpiY) {
715     if (mRenderWindow) {
716         mRenderWindow->setDisplayConfigs(configId, w, h, dpiX, dpiY);
717     }
718 }
719 
setDisplayActiveConfig(int configId)720 void RendererImpl::setDisplayActiveConfig(int configId) {
721     if (mRenderWindow) {
722         mRenderWindow->setDisplayActiveConfig(configId);
723     }
724 }
725 
getEglDispatch()726 const void* RendererImpl::getEglDispatch() {
727 #if GFXSTREAM_ENABLE_HOST_GLES
728     return FrameBuffer::getFB()->getEglDispatch();
729 #else
730     return nullptr;
731 #endif
732 }
733 
getGles2Dispatch()734 const void* RendererImpl::getGles2Dispatch() {
735 #if GFXSTREAM_ENABLE_HOST_GLES
736     return FrameBuffer::getFB()->getGles2Dispatch();
737 #else
738     return nullptr;
739 #endif
740 }
741 
742 }  // namespace gfxstream
743