| // Copyright 2014-2015 The Android Open Source Project |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #ifndef ANDROID_EMUGL_LIBRENDER_RENDER_WINDOW_H |
| #define ANDROID_EMUGL_LIBRENDER_RENDER_WINDOW_H |
| |
| #include "render-utils/render_api.h" |
| |
| #include "aemu/base/synchronization/MessageChannel.h" |
| #include "aemu/base/threads/FunctorThread.h" |
| #include "aemu/base/threads/Thread.h" |
| #include "gfxstream/host/Features.h" |
| |
| namespace gfxstream { |
| |
| class RenderWindowChannel; |
| struct RenderWindowMessage; |
| |
| // Helper class used to manage the sub-window that displays the emulated GPU |
| // output. To use it, do the following: |
| // |
| // 1) Create a new instance, passing the size of the emulated accelerated |
| // framebuffer in pixels you need. |
| // |
| // 2) Check isValid() after construction. If false, the library could not |
| // initialize the class properly, and one should abort. |
| // |
| // 3) Optional: call setPostCallback() to specify a callback function which |
| // will be called everytime a new frame is drawn. |
| // |
| // 4) Call setupSubWindow() to setup a new sub-window within the UI window. |
| // One can call removeSubWindow() to remove it, and one can call |
| // setupSubWindow() + removeSubWindow() any number of time (e.g. for |
| // changing the position / rotation of the subwindow). |
| // |
| // 5) Optional: call setRotation() to only change the display rotation of |
| // the sub-window content. |
| // |
| // 6) Call repaint() to force a repaint(). |
| // |
| class RenderWindow { |
| public: |
| // Create new instance. |width| and |height| are the dimensions of the |
| // emulated accelerated framebuffer. |use_thread| can be true to force |
| // the use of a separate thread, which might be required on some platforms |
| // to avoid GL-realted corruption issues in the main window. Call |
| // isValid() after construction to verify that it worked properly. |
| // |
| // |use_sub_window| is true if the client will call setupSubWindow(), |
| // and false if it will call setPostCallback(). |
| // |
| // Note that this call doesn't display anything, it just initializes |
| // the library, use setupSubWindow() to display something. |
| RenderWindow(int width, int height, gfxstream::host::FeatureSet features, |
| bool use_thread, bool use_sub_window, bool egl2egl); |
| |
| // Destructor. This will automatically call removeSubWindow() is needed. |
| ~RenderWindow(); |
| |
| // Returns true if the RenderWindow instance is valid, which really |
| // means that the constructor succeeded. |
| bool isValid() const { return mValid; } |
| |
| // Return misc. GL strings to the caller. On success, return true and sets |
| // |*vendor| to the GL vendor string, |*renderer| to the GL renderer one, |
| // and |*version| to the GL version one. On failure, return false. |
| bool getHardwareStrings(const char** vendor, |
| const char** renderer, |
| const char** version); |
| |
| // Specify a function that will be called everytime a new frame is |
| // displayed. This is relatively slow but allows one to capture the |
| // output. |
| void setPostCallback(Renderer::OnPostCallback onPost, void* onPostContext, uint32_t displayId, |
| bool useBgraReadback = false); |
| |
| bool asyncReadbackSupported(); |
| Renderer::ReadPixelsCallback getReadPixelsCallback(); |
| Renderer::FlushReadPixelPipeline getFlushReadPixelPipeline(); |
| |
| // Start displaying the emulated framebuffer using a sub-window of a |
| // parent |window| id. |wx|, |wy|, |ww| and |wh| are the position |
| // and dimension of the sub-window, relative to its parent. |
| // |fbw| and |fbh| are the dimensions of the underlying guest framebuffer. |
| // |dpr| is the device pixel ratio for the monitor, which is required for |
| // higher-density displays (such as retina). |
| // |rotation| is a clockwise-rotation for the content. Only multiples of |
| // 90. are accepted. Returns true on success, false otherwise. |
| // |
| // If the subwindow already exists, this function will update |
| // the dimensions of the subwindow, backing framebuffer, and rendering |
| // pipeline to reflect the new values. |
| // |
| // One can call removeSubWindow() to remove the sub-window. |
| bool setupSubWindow(FBNativeWindowType window, |
| int wx, |
| int wy, |
| int ww, |
| int wh, |
| int fbw, |
| int fbh, |
| float dpr, |
| float rotation, |
| bool deleteExisting, |
| bool hideWindow); |
| |
| // Remove the sub-window created by calling setupSubWindow(). |
| // Note that this doesn't discard the content of the emulated framebuffer, |
| // it just hides it from the main window. Returns true on success, false |
| // otherwise. |
| bool removeSubWindow(); |
| |
| // Change the display rotation on the fly. |zRot| is a clockwise rotation |
| // angle in degrees. Only multiples of 90. are accepted. |
| void setRotation(float zRot); |
| |
| // Change the display translation. |px|,|py| are numbers between 0 and 1, |
| // with (0,0) indicating "align the bottom left of the framebuffer with the |
| // bottom left of the subwindow", and (1,1) indicating "align the top right of |
| // the framebuffer with the top right of the subwindow." |
| void setTranslation(float px, float py); |
| |
| // Receive a screen mask and pass it to TextureDraw |
| void setScreenMask(int width, int height, const unsigned char* rgbaData); |
| |
| // Force a repaint of the whole content into the sub-window. |
| void repaint(); |
| |
| // Returns whether or not the guest posted a frame. For checking emulator |
| // liveness. |
| bool hasGuestPostedAFrame(); |
| // Resets whether the guest has posted a frame. |
| void resetGuestPostedAFrame(); |
| |
| void setPaused(bool paused); |
| |
| void addListener(Renderer::FrameBufferChangeEventListener* listener); |
| void removeListener(Renderer::FrameBufferChangeEventListener* listener); |
| |
| void setVsyncHz(int vsyncHz); |
| void setDisplayConfigs(int configId, int w, int h, int dpiX, int dpiY); |
| void setDisplayActiveConfig(int configId); |
| private: |
| bool processMessage(const RenderWindowMessage& msg); |
| bool useThread() const { return mThread != nullptr; } |
| |
| bool mValid = false; |
| bool mHasSubWindow = false; |
| android::base::Thread* mThread = nullptr; |
| RenderWindowChannel* mChannel = nullptr; |
| |
| // A worker thread to run repost() commands asynchronously. |
| enum class RepostCommand : char { |
| Repost, Sync |
| }; |
| android::base::MessageChannel<RepostCommand, 10> mRepostCommands; |
| android::base::FunctorThread mRepostThread; |
| |
| bool mPaused = false; |
| }; |
| |
| } // namespace gfxstream |
| |
| #endif // ANDROID_EMUGL_LIBRENDER_RENDER_WINDOW_H |