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