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