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 ContextImpl *createContext(const gl::State &state, 113 gl::ErrorSet *errorSet, 114 const egl::Config *configuration, 115 const gl::Context *shareContext, 116 const egl::AttributeMap &attribs) override; 117 118 egl::Error makeCurrent(egl::Display *display, 119 egl::Surface *drawSurface, 120 egl::Surface *readSurface, 121 gl::Context *context) override; 122 123 egl::ConfigSet generateConfigs() override; 124 125 bool isValidNativeWindow(EGLNativeWindowType window) const override; 126 127 // TODO(fjhenigman) Implement this. 128 // Swap interval can be set globally or per drawable. 129 // This function will make sure the drawable's swap interval is the 130 // one required so that the subsequent swapBuffers acts as expected. 131 void setSwapInterval(EGLSurface drawable, SwapControlData *data); 132 133 WorkerContext *createWorkerContext(std::string *infoLog, 134 EGLContext sharedContext, 135 const native_egl::AttributeVector workerAttribs) override; 136 137 private: 138 void generateExtensions(egl::DisplayExtensions *outExtensions) const override; 139 EGLint fixSurfaceType(EGLint surfaceType) const override; 140 141 GLuint makeShader(GLuint type, const char *src); 142 void drawBuffer(const gl::Context *context, Buffer *buffer); 143 void drawWithTexture(const gl::Context *context, Buffer *buffer); 144 void flushGL(); 145 bool hasUsableScreen(int fd); 146 void presentScreen(); 147 static void pageFlipHandler(int fd, 148 unsigned int sequence, 149 unsigned int tv_sec, 150 unsigned int tv_usec, 151 void *data); 152 void pageFlipHandler(unsigned int sequence, uint64_t tv); 153 bool validateEglConfig(const EGLint *configAttribs); 154 155 gbm_device *mGBM; 156 drmModeConnectorPtr mConnector; 157 drmModeModeInfoPtr mMode; 158 drmModeCrtcPtr mCRTC; 159 bool mSetCRTC; 160 161 int32_t mWidth; 162 int32_t mHeight; 163 164 // Three scanout buffers cycle through four states. The state of a buffer 165 // is indicated by which of these pointers points to it. 166 // TODO(fjhenigman) It might be simpler/clearer to use a ring buffer. 167 Buffer *mScanning; 168 Buffer *mPending; 169 Buffer *mDrawing; 170 Buffer *mUnused; 171 172 GLuint mProgram; 173 GLuint mVertexShader; 174 GLuint mFragmentShader; 175 GLuint mVertexBuffer; 176 GLuint mIndexBuffer; 177 GLint mCenterUniform; 178 GLint mWindowSizeUniform; 179 GLint mBorderSizeUniform; 180 GLint mDepthUniform; 181 }; 182 } // namespace rx 183 184 #endif // LIBANGLE_RENDERER_GL_EGL_GBM_DISPLAYGBM_H_ 185