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