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