1 // 2 // Copyright 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 // DisplayGbm.h: Gbm implementation of egl::Display 8 9 #ifndef LIBANGLE_RENDERER_GL_EGL_GBM_DISPLAYGBM_H_ 10 #define LIBANGLE_RENDERER_GL_EGL_GBM_DISPLAYGBM_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 class RendererEGL; 32 33 struct SwapControlData; 34 35 // TODO(fjhenigman) Implement swap control. The SwapControlData struct will be used for that. 36 class DisplayGbm final : public DisplayEGL 37 { 38 public: 39 struct NativeWindow 40 { 41 int32_t x; 42 int32_t y; 43 int32_t width; 44 int32_t height; 45 int32_t borderWidth; 46 int32_t borderHeight; 47 int32_t visible; 48 int32_t depth; 49 }; 50 51 class Buffer final : angle::NonCopyable 52 { 53 public: 54 Buffer(DisplayGbm *display, 55 uint32_t useFlags, 56 uint32_t gbmFormat, 57 uint32_t drmFormat, 58 uint32_t drmFormatFB, 59 int depthBits, 60 int stencilBits); 61 62 ~Buffer(); 63 bool initialize(const NativeWindow *window); 64 bool initialize(int32_t width, int32_t height); 65 void reset(); 66 bool resize(int32_t width, int32_t height); 67 GLuint createGLFB(const gl::Context *context); 68 FramebufferGL *framebufferGL(const gl::Context *context, const gl::FramebufferState &state); 69 void present(const gl::Context *context); 70 uint32_t getDRMFB(); 71 void bindTexImage(); 72 GLuint getTexture(); getWidth()73 int32_t getWidth() const { return mWidth; } getHeight()74 int32_t getHeight() const { return mHeight; } getNative()75 const NativeWindow *getNative() const { return mNative; } 76 77 private: 78 bool createRenderbuffers(); 79 80 DisplayGbm *mDisplay; 81 const NativeWindow *mNative; 82 int mWidth; 83 int mHeight; 84 const int mDepthBits; 85 const int mStencilBits; 86 const uint32_t mUseFlags; 87 const uint32_t mGBMFormat; 88 const uint32_t mDRMFormat; 89 const uint32_t mDRMFormatFB; 90 gbm_bo *mBO; 91 int mDMABuf; 92 bool mHasDRMFB; 93 uint32_t mDRMFB; 94 EGLImageKHR mImage; 95 GLuint mColorBuffer; 96 GLuint mDSBuffer; 97 GLuint mTexture; 98 }; 99 100 DisplayGbm(const egl::DisplayState &state); 101 ~DisplayGbm() override; 102 103 egl::Error initialize(egl::Display *display) override; 104 void terminate() override; 105 106 SurfaceImpl *createWindowSurface(const egl::SurfaceState &state, 107 EGLNativeWindowType window, 108 const egl::AttributeMap &attribs) override; 109 SurfaceImpl *createPbufferSurface(const egl::SurfaceState &state, 110 const egl::AttributeMap &attribs) override; 111 112 bool isValidNativeWindow(EGLNativeWindowType window) const override; 113 114 // TODO(fjhenigman) Implement this. 115 // Swap interval can be set globally or per drawable. 116 // This function will make sure the drawable's swap interval is the 117 // one required so that the subsequent swapBuffers acts as expected. 118 void setSwapInterval(EGLSurface drawable, SwapControlData *data); 119 120 private: 121 EGLint fixSurfaceType(EGLint surfaceType) const override; 122 123 GLuint makeShader(GLuint type, const char *src); 124 void drawBuffer(const gl::Context *context, Buffer *buffer); 125 void drawWithTexture(const gl::Context *context, Buffer *buffer); 126 void flushGL(); 127 bool hasUsableScreen(int fd); 128 void presentScreen(); 129 static void pageFlipHandler(int fd, 130 unsigned int sequence, 131 unsigned int tv_sec, 132 unsigned int tv_usec, 133 void *data); 134 void pageFlipHandler(unsigned int sequence, uint64_t tv); 135 136 gbm_device *mGBM; 137 drmModeConnectorPtr mConnector; 138 drmModeModeInfoPtr mMode; 139 drmModeCrtcPtr mCRTC; 140 bool mSetCRTC; 141 142 int32_t mWidth; 143 int32_t mHeight; 144 145 // Three scanout buffers cycle through four states. The state of a buffer 146 // is indicated by which of these pointers points to it. 147 // TODO(fjhenigman) It might be simpler/clearer to use a ring buffer. 148 Buffer *mScanning; 149 Buffer *mPending; 150 Buffer *mDrawing; 151 Buffer *mUnused; 152 153 GLuint mProgram; 154 GLuint mVertexShader; 155 GLuint mFragmentShader; 156 GLuint mVertexBuffer; 157 GLuint mIndexBuffer; 158 GLint mCenterUniform; 159 GLint mWindowSizeUniform; 160 GLint mBorderSizeUniform; 161 GLint mDepthUniform; 162 }; 163 } // namespace rx 164 165 #endif // LIBANGLE_RENDERER_GL_EGL_GBM_DISPLAYGBM_H_ 166