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