• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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