• 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 #pragma once
15 
16 #include "aemu/base/files/Stream.h"
17 #include "aemu/base/ring_buffer.h"
18 #include "host-common/address_space_graphics_types.h"
19 #include "render-utils/RenderChannel.h"
20 #include "render-utils/render_api_platform_types.h"
21 #include "render-utils/virtio_gpu_ops.h"
22 #include "snapshot/common.h"
23 
24 #include <functional>
25 #include <memory>
26 #include <optional>
27 #include <string>
28 
29 namespace android_studio {
30 class EmulatorGLESUsages;
31 }
32 
33 namespace gfxstream {
34 
35 typedef struct {
36     int x, y;
37 } Pos;
38 
39 typedef struct {
40     int w, h;
41 } Size;
42 
43 // A structure used to model a rectangle in pixels.
44 // |pos| is the location of the rectangle's origin (top-left corner).
45 // |size| is the dimension in integer pixels of the rectangle.
46 typedef struct {
47     Pos pos;
48     Size size;
49 } Rect;
50 
51 enum class FrameBufferChange {
52     FrameReady = 0,
53 };
54 
55 struct FrameBufferChangeEvent {
56     FrameBufferChange change;
57     uint64_t frameNumber;
58 };
59 
60 // Renderer - an object that manages a single OpenGL window used for drawing
61 // and is able to create individual render channels for that window.
62 //
63 class Renderer {
64 public:
65     // createRenderChannel - create a separate channel for the rendering data.
66     // This call instantiates a new object that waits for the serialized data
67     // from the guest, deserializes it, executes the passed GL commands and
68     // returns the results back.
69     // |loadStream| - if not NULL, RenderChannel uses it to load saved state
70     //   asynchronously on its own thread. |loadStream| can be used right after
71     //   the call as all the required data is copied here synchronously.
72     virtual RenderChannelPtr createRenderChannel(
73             android::base::Stream* loadStream = nullptr,
74             uint32_t virtioGpuContextId = -1) = 0;
75 
76     // analog of createRenderChannel, but for the address space graphics device
77     virtual void* addressSpaceGraphicsConsumerCreate(
78         struct asg_context,
79         android::base::Stream* loadStream,
80         android::emulation::asg::ConsumerCallbacks,
81         uint32_t contextId, uint32_t capsetId,
82         std::optional<std::string> nameOpt) = 0;
83     virtual void addressSpaceGraphicsConsumerDestroy(void*) = 0;
84     virtual void addressSpaceGraphicsConsumerPreSave(void* consumer) = 0;
85     virtual void addressSpaceGraphicsConsumerSave(
86             void* consumer,
87             android::base::Stream* stream) = 0;
88     virtual void addressSpaceGraphicsConsumerPostSave(void* consumer) = 0;
89     virtual void addressSpaceGraphicsConsumerRegisterPostLoadRenderThread(
90             void* consumer) = 0;
91 
92     // getHardwareStrings - describe the GPU hardware and driver.
93     // The underlying GL's vendor/renderer/version strings are returned to the
94     // caller.
95     struct HardwareStrings {
96         std::string vendor;
97         std::string renderer;
98         std::string version;
99     };
100     virtual HardwareStrings getHardwareStrings() = 0;
101 
102     // A per-frame callback can be registered with setPostCallback(); to remove
103     // it pass an empty callback. While a callback is registered, the renderer
104     // will call it just before each new frame is displayed, providing a copy of
105     // the framebuffer contents.
106     //
107     // The callback will be called from one of the renderer's threads, so will
108     // probably need synchronization on any data structures it modifies. The
109     // pixels buffer may be overwritten as soon as the callback returns; it
110     // doesn't need to be synchronized, but if the callback needs the pixels
111     // afterwards it must copy them.
112     //
113     // The pixels buffer is intentionally not const: the callback may modify the
114     // data without copying to another buffer if it wants, e.g. in-place RGBA to
115     // RGB conversion, or in-place y-inversion.
116     //
117     // Parameters are:
118     //   displayId      Default is 0. Can also be 1 to 10 if multi display
119     //                  configured.
120     //   width, height  Dimensions of the image, in pixels. Rows are tightly
121     //                  packed; there is no inter-row padding.
122     //   ydir           Indicates row order: 1 means top-to-bottom order, -1
123     //                  means bottom-to-top order.
124     //   format, type   Format and type GL enums, as used in glTexImage2D() or
125     //                  glReadPixels(), describing the pixel format.
126     //   pixels         The framebuffer image.
127     //
128     // In the first implementation, ydir is always -1 (bottom to top), format
129     // and type are always GL_RGBA and GL_UNSIGNED_BYTE, and the width and
130     // height will always be the same as the ones used to create the renderer.
131     using OnPostCallback = void (*)(void* context,
132                                     uint32_t displayId,
133                                     int width,
134                                     int height,
135                                     int ydir,
136                                     int format,
137                                     int type,
138                                     unsigned char* pixels);
139     virtual void setPostCallback(OnPostCallback onPost,
140                                  void* context,
141                                  bool useBgraReadback,
142                                  uint32_t displayId) = 0;
143 
144     using FrameBufferChangeEventListener =
145             std::function<void(const FrameBufferChangeEvent evt)>;
146 
147     // Adds a FramebufferChangeEventListener. The listener will be invoked
148     // whenever a new frame has been made available and is to be rendered on
149     // screen. You should do as little work as possible on this callback.
150     virtual void addListener(FrameBufferChangeEventListener* listener) = 0;
151 
152     // Removes the listener.
153     virtual void removeListener(FrameBufferChangeEventListener* listener) = 0;
154 
155     // Async readback API
156     virtual bool asyncReadbackSupported() = 0;
157 
158     // Separate callback to get RGBA Pixels in async readback mode.
159     using ReadPixelsCallback = void (*)(void* pixels,
160                                         uint32_t bytes,
161                                         uint32_t displayId);
162     virtual ReadPixelsCallback getReadPixelsCallback() = 0;
163 
164     using FlushReadPixelPipeline = void (*)(int displayId);
165     // Flushes the pipeline by duplicating the last frame and informing
166     // the async callback that a new frame is available if no reads are
167     // active
168     virtual FlushReadPixelPipeline getFlushReadPixelPipeline() = 0;
169 
170     // showOpenGLSubwindow -
171     //     Create or modify a native subwindow which is a child of 'window'
172     //     to be used for framebuffer display. If a subwindow already exists,
173     //     its properties will be updated to match the given parameters.
174     //     wx,wy is the top left corner of the rendering subwindow.
175     //     ww,wh are the dimensions of the rendering subwindow.
176     //     fbw,fbh are the dimensions of the underlying guest framebuffer.
177     //     dpr is the device pixel ratio, which is needed for higher density
178     //     displays like retina.
179     //     zRot is the rotation to apply on the framebuffer display image.
180     //
181     //     Return true on success, false on failure, which can happen when using
182     //     a software-only renderer like OSMesa. In this case, the client should
183     //     call setPostCallback to get the content of each new frame when it is
184     //     posted, and will be responsible for displaying it.
185     virtual bool showOpenGLSubwindow(FBNativeWindowType window,
186                                      int wx,
187                                      int wy,
188                                      int ww,
189                                      int wh,
190                                      int fbw,
191                                      int fbh,
192                                      float dpr,
193                                      float zRot,
194                                      bool deleteExisting,
195                                      bool hideWindow) = 0;
196 
197     // destroyOpenGLSubwindow -
198     //   destroys the created native subwindow. Once destroyed,
199     //   Framebuffer content will not be visible until a new
200     //   subwindow will be created.
201     virtual bool destroyOpenGLSubwindow() = 0;
202 
203     // setOpenGLDisplayRotation -
204     //    set the framebuffer display image rotation in units
205     //    of degrees around the z axis
206     virtual void setOpenGLDisplayRotation(float zRot) = 0;
207 
208     // setOpenGLDisplayTranslation
209     //    change what coordinate of the guest framebuffer will be displayed at
210     //    the corner of the GPU sub-window. Specifically, |px| and |py| = 0
211     //    means
212     //    align the bottom-left of the framebuffer with the bottom-left of the
213     //    sub-window, and |px| and |py| = 1 means align the top right of the
214     //    framebuffer with the top right of the sub-window. Intermediate values
215     //    interpolate between these states.
216     virtual void setOpenGLDisplayTranslation(float px, float py) = 0;
217 
218     // repaintOpenGLDisplay -
219     //    causes the OpenGL subwindow to get repainted with the
220     //    latest framebuffer content.
221     virtual void repaintOpenGLDisplay() = 0;
222 
223     // hasGuestPostedAFrame / resetGuestPostedAFrame -
224     //     for liveness checking; queries whether or not the guest
225     //     has successfully issued a framebuffer post to the emulator,
226     //     and a method to reset that state.
227     virtual bool hasGuestPostedAFrame() = 0;
228     virtual void resetGuestPostedAFrame() = 0;
229 
230     // setScreenMask -
231     //    provide the image that should be overlayed on the
232     //    device screen to mask that screen
233     virtual void setScreenMask(int width,
234                                int height,
235                                const unsigned char* rgbaData) = 0;
236 
237     // setMultiDisplay
238     //    add/modify/del multi-display window
239     virtual void setMultiDisplay(uint32_t id,
240                                  int32_t x,
241                                  int32_t y,
242                                  uint32_t w,
243                                  uint32_t h,
244                                  uint32_t dpi,
245                                  bool add) = 0;
246     // setMultiDisplayColorBuffer
247     //    bind ColorBuffer to the display
248     virtual void setMultiDisplayColorBuffer(uint32_t id, uint32_t cb) = 0;
249 
250     // onGuestGraphicsProcessCreate
251     //    Notify the renderer that a new graphics process is created. Used to create process
252     //    specific resources.
253     virtual void onGuestGraphicsProcessCreate(uint64_t puid) = 0;
254     // cleanupProcGLObjects -
255     //    clean up all per-process resources when guest process exits (or is
256     // killed). Such resources include color buffer handles and EglImage handles.
257     // TODO(kaiyili): rename this interface to onGuestGraphicsProcessDestroy.
258     virtual void cleanupProcGLObjects(uint64_t puid) = 0;
259 
260     // Wait for cleanupProcGLObjects to finish.
261     virtual void waitForProcessCleanup() = 0;
262 
263     virtual struct AndroidVirtioGpuOps* getVirtioGpuOps(void) = 0;
264 
265     // Stops all channels and render threads. The renderer cannot be used after
266     // stopped.
267     virtual void stop(bool wait) = 0;
268 
269     // Waits for all channels to finish and deletes all render threads.
270     // The renderer can still be used after finish().
271     virtual void finish() = 0;
272 
273     // Pauses all channels to prepare for snapshot saving.
274     virtual void pauseAllPreSave() = 0;
275 
276     // Resumes all channels after snapshot saving or loading.
277     virtual void resumeAll(bool waitForSave = true) = 0;
278 
279     virtual void save(
280             android::base::Stream* stream,
281             const android::snapshot::ITextureSaverPtr& textureSaver) = 0;
282     virtual bool load(
283             android::base::Stream* stream,
284             const android::snapshot::ITextureLoaderPtr& textureLoader) = 0;
285 
286     // Fill GLES usage protobuf
287     virtual void fillGLESUsages(android_studio::EmulatorGLESUsages*) = 0;
288 
289     // Saves a screenshot of the previous frame.
290     // nChannels should be 3 (RGB) or 4 (RGBA).
291     // You must provide a pre-allocated buffer of sufficient
292     // size. Returns 0 on success. In the case of failure and if *cPixels != 0
293     // you can call this function again with a buffer of size *cPixels. cPixels
294     // should usually be at at least desiredWidth * desiredHeight * nChannels.
295     //
296     // In practice the buffer should be > desiredWidth *
297     // desiredHeight * nChannels.
298     //
299     // Note: Do not call this function again if it fails and *cPixels == 0
300     //  swiftshader_indirect does not work with 3 channels
301     //
302     // This function supports rectangle snipping by
303     // providing an |rect| parameter. The default value of {{0,0}, {0,0}}
304     // indicates the users wants to snip the entire screen.
305     // - |rect|  represents a rectangle within the screen defined by
306     // desiredWidth and desiredHeight.
307     virtual int getScreenshot(unsigned int nChannels, unsigned int* width, unsigned int* height,
308                               uint8_t* pixels, size_t* cPixels, int displayId = 0,
309                               int desiredWidth = 0, int desiredHeight = 0, int desiredRotation = 0,
310                               Rect rect = {{0, 0}, {0, 0}}) = 0;
311     virtual void snapshotOperationCallback(
312             int snapshotterOp,
313             int snapshotterStage) = 0;
314 
315     virtual void setVsyncHz(int vsyncHz) = 0;
316     virtual void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY) = 0;
317     virtual void setDisplayActiveConfig(int configId) = 0;
318 
319     virtual const void* getEglDispatch() = 0;
320     virtual const void* getGles2Dispatch() = 0;
321 
322 protected:
323     ~Renderer() = default;
324 };
325 
326 using RendererPtr = std::shared_ptr<Renderer>;
327 
328 }  // namespace gfxstream
329