1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #pragma once 17 18 #include <EGL/egl.h> // for EGLContext, EGLSurface 19 #include <GLES3/gl3.h> // for GLuint 20 #include <map> // for map 21 #include <stdint.h> // for uint32_t 22 #include <vector> // for vector 23 24 #include "base/Compiler.h" // for DISALLOW_COPY_AND_ASSIGN 25 #include "base/Lock.h" // for Lock 26 27 class ColorBuffer; 28 class FrameBuffer; 29 struct RenderThreadInfo; 30 31 // This class implements async readback of emugl ColorBuffers. 32 // It is meant to run on both the emugl framebuffer posting thread 33 // and a separate GL thread, with two main points of interaction: 34 class ReadbackWorker { 35 public: 36 ReadbackWorker() = default; 37 ~ReadbackWorker(); 38 39 // GL initialization (must be on the thread that 40 // will run getPixels) 41 void initGL(); 42 43 // doNextReadback(): Call this from the emugl FrameBuffer::post thread 44 // or similar rendering thread. 45 // This will trigger an async glReadPixels of the current framebuffer. 46 // The post callback of Framebuffer will also be triggered, but 47 // in async mode it should do minimal work that involves |fbImage|. 48 // |repaint|: flag to prime async readback with multiple iterations 49 // so that the consumer of readback doesn't lag behind. 50 // |readbackBgra|: Whether to force the readback format as GL_BGRA_EXT, 51 // so that we get (depending on driver quality, heh) a gpu conversion of the 52 // readback image that is suitable for webrtc, which expects formats like that. 53 void doNextReadback(uint32_t displayId, ColorBuffer* cb, void* fbImage, bool repaint, bool readbackBgra); 54 55 // getPixels(): Run this on a separate GL thread. This retrieves the 56 // latest framebuffer that has been posted and read with doNextReadback. 57 // This is meant for apps like video encoding to use as input; they will 58 // need to do synchronized communication with the thread ReadbackWorker 59 // is running on. 60 void getPixels(uint32_t displayId, void* out, uint32_t bytes); 61 62 // Duplicates the last frame and generates a post events if 63 // there are no read events active. 64 // This is usually called when there was no doNextReadback activity 65 // for a few ms, to guarantee that end users see the final frame. 66 void flushPipeline(uint32_t displayId); 67 68 void setRecordDisplay(uint32_t displayId, uint32_t w, uint32_t h, bool add); 69 70 class recordDisplay { 71 public: 72 recordDisplay() = default; 73 recordDisplay(uint32_t displayId, uint32_t w, uint32_t h); 74 public: 75 uint32_t mReadPixelsIndexEven = 0; 76 uint32_t mReadPixelsIndexOdd = 1; 77 uint32_t mPrevReadPixelsIndex = 1; 78 uint32_t mMapCopyIndex = 0; 79 bool mIsCopying = false; 80 uint32_t mBufferSize = 0; 81 std::vector<GLuint> mBuffers = {}; 82 uint32_t m_readbackCount = 0; 83 uint32_t mDisplayId = 0; 84 }; 85 86 private: 87 EGLContext mContext; 88 EGLContext mFlushContext; 89 EGLSurface mSurf; 90 EGLSurface mFlushSurf; 91 92 FrameBuffer* mFb; 93 android::base::Lock mLock; 94 95 std::map<uint32_t, recordDisplay> mRecordDisplays; 96 97 DISALLOW_COPY_AND_ASSIGN(ReadbackWorker); 98 }; 99