1 // 2 // Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // DisplayOzone.h: Ozone implementation of egl::Display 8 9 #ifndef LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_ 10 #define LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_ 11 12 #include <xf86drm.h> 13 #include <xf86drmMode.h> 14 15 #include <string> 16 17 #include "libANGLE/renderer/gl/egl/DisplayEGL.h" 18 19 struct gbm_device; 20 struct gbm_bo; 21 22 namespace gl 23 { 24 class FramebufferState; 25 } 26 27 namespace rx 28 { 29 30 class FramebufferGL; 31 32 // TODO(fjhenigman) Implement swap control. The following struct will be used for that. 33 // State-tracking data for the swap control to allow DisplayOzone to remember per 34 // drawable information for swap control. 35 struct SwapControlData final 36 { 37 SwapControlData(); 38 39 // Set by the drawable 40 int targetSwapInterval; 41 42 // DisplayOzone-side state-tracking 43 int maxSwapInterval; 44 int currentSwapInterval; 45 }; 46 47 class DisplayOzone final : public DisplayEGL 48 { 49 public: 50 struct NativeWindow 51 { 52 int32_t x; 53 int32_t y; 54 int32_t width; 55 int32_t height; 56 int32_t borderWidth; 57 int32_t borderHeight; 58 int32_t visible; 59 int32_t depth; 60 }; 61 62 class Buffer final : angle::NonCopyable 63 { 64 public: 65 Buffer(DisplayOzone *display, 66 uint32_t useFlags, 67 uint32_t gbmFormat, 68 uint32_t drmFormat, 69 uint32_t drmFormatFB, 70 int depthBits, 71 int stencilBits); 72 73 ~Buffer(); 74 bool initialize(const NativeWindow *window); 75 bool initialize(int32_t width, int32_t height); 76 void reset(); 77 bool resize(int32_t width, int32_t height); 78 FramebufferGL *framebufferGL(const gl::FramebufferState &state); 79 void present(); 80 uint32_t getDRMFB(); 81 void bindTexImage(); 82 GLuint getTexture(); getWidth()83 int32_t getWidth() const { return mWidth; } getHeight()84 int32_t getHeight() const { return mHeight; } getGLFB()85 GLuint getGLFB() const { return mGLFB; } getNative()86 const NativeWindow *getNative() const { return mNative; } 87 88 private: 89 DisplayOzone *mDisplay; 90 const NativeWindow *mNative; 91 int mWidth; 92 int mHeight; 93 const int mDepthBits; 94 const int mStencilBits; 95 const uint32_t mUseFlags; 96 const uint32_t mGBMFormat; 97 const uint32_t mDRMFormat; 98 const uint32_t mDRMFormatFB; 99 gbm_bo *mBO; 100 int mDMABuf; 101 bool mHasDRMFB; 102 uint32_t mDRMFB; 103 EGLImageKHR mImage; 104 GLuint mColorBuffer; 105 GLuint mDSBuffer; 106 GLuint mGLFB; 107 GLuint mTexture; 108 }; 109 110 DisplayOzone(); 111 ~DisplayOzone() override; 112 113 egl::Error initialize(egl::Display *display) override; 114 void terminate() override; 115 116 SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, 117 const egl::Config *configuration, 118 EGLNativeWindowType window, 119 const egl::AttributeMap &attribs) override; 120 SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, 121 const egl::Config *configuration, 122 const egl::AttributeMap &attribs) override; 123 SurfaceImpl *createPbufferFromClientBuffer(const egl::SurfaceState &state, 124 const egl::Config *configuration, 125 EGLenum buftype, 126 EGLClientBuffer clientBuffer, 127 const egl::AttributeMap &attribs) override; 128 SurfaceImpl *createPixmapSurface(const egl::SurfaceState &state, 129 const egl::Config *configuration, 130 NativePixmapType nativePixmap, 131 const egl::AttributeMap &attribs) override; 132 133 egl::ConfigSet generateConfigs() override; 134 135 bool testDeviceLost() override; 136 egl::Error restoreLostDevice() override; 137 138 bool isValidNativeWindow(EGLNativeWindowType window) const override; 139 140 egl::Error getDevice(DeviceImpl **device) override; 141 142 egl::Error waitClient() const override; 143 egl::Error waitNative(EGLint engine, 144 egl::Surface *drawSurface, 145 egl::Surface *readSurface) const override; 146 147 // TODO(fjhenigman) Implement this. 148 // Swap interval can be set globally or per drawable. 149 // This function will make sure the drawable's swap interval is the 150 // one required so that the subsequent swapBuffers acts as expected. 151 void setSwapInterval(EGLSurface drawable, SwapControlData *data); 152 153 egl::Error getDriverVersion(std::string *version) const override; 154 155 private: 156 GLuint makeShader(GLuint type, const char *src); 157 void drawBuffer(Buffer *buffer); 158 void drawWithBlit(Buffer *buffer); 159 void drawWithTexture(Buffer *buffer); 160 void flushGL(); 161 void presentScreen(); 162 static void pageFlipHandler(int fd, 163 unsigned int sequence, 164 unsigned int tv_sec, 165 unsigned int tv_usec, 166 void *data); 167 void pageFlipHandler(unsigned int sequence, uint64_t tv); 168 169 // TODO(fjhenigman) Implement swap control. The following stuff will be used for that. 170 enum class SwapControl 171 { 172 ABSENT, 173 EXT, 174 MESA, 175 SGI, 176 }; 177 SwapControl mSwapControl; 178 int mMinSwapInterval; 179 int mMaxSwapInterval; 180 int mCurrentSwapInterval; 181 182 gbm_device *mGBM; 183 drmModeConnectorPtr mConnector; 184 drmModeModeInfoPtr mMode; 185 drmModeCrtcPtr mCRTC; 186 bool mSetCRTC; 187 188 int32_t mWidth; 189 int32_t mHeight; 190 191 // Three scanout buffers cycle through four states. The state of a buffer 192 // is indicated by which of these pointers points to it. 193 // TODO(fjhenigman) It might be simpler/clearer to use a ring buffer. 194 Buffer *mScanning; 195 Buffer *mPending; 196 Buffer *mDrawing; 197 Buffer *mUnused; 198 199 GLuint mProgram; 200 GLuint mVertexShader; 201 GLuint mFragmentShader; 202 GLuint mVertexBuffer; 203 GLuint mIndexBuffer; 204 GLint mCenterUniform; 205 GLint mWindowSizeUniform; 206 GLint mBorderSizeUniform; 207 GLint mDepthUniform; 208 }; 209 } // namespace rx 210 211 #endif // LIBANGLE_RENDERER_GL_EGL_OZONE_DISPLAYOZONE_H_ 212