Gnash  0.8.11dev
eglDevice.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 // Free Software Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 //
19 
20 #ifndef __EGL_DEVICE_H__
21 #define __EGL_DEVICE_H__ 1
22 
23 #ifdef HAVE_CONFIG_H
24 #include "gnashconfig.h"
25 #endif
26 
27 #include <memory>
28 
29 #ifdef HAVE_X11_X_H
30 #include "x11/X11Device.h"
31 #endif
32 #include "GnashDevice.h"
33 
34 #ifdef HAVE_EGL_EGL_H
35 # include <EGL/egl.h>
36 #else
37 # error "This file needs EGL, which is part of OpenGL-ES"
38 #endif
39 
40 #include "Point2d.h"
41 
42 namespace gnash {
43 
44 namespace renderer {
45 
46 struct eglVertex {
47  eglVertex(float x, float y)
48  : _x(x), _y(y) { }
49 
50  eglVertex(const point& p)
51  : _x(p.x), _y(p.y) { }
52  float _x;
53  float _y;
54 };
55 
56 class EGLDevice : public GnashDevice
57 {
58  public:
59  typedef enum {LOW, MEDIUM, HIGH} quality_e;
60  EGLDevice();
61  EGLDevice(int argc, char *argv[]);
63 
64  virtual ~EGLDevice();
65 
66  dtype_t getType() { return EGL; };
67 
68  // Initialize EGL Device layer
69  bool initDevice(int argc, char *argv[]);
70 
71  // Initialize EGL Window layer
72  bool attachWindow(GnashDevice::native_window_t window);
73 
74  // Utility methods not in the base class
76  const char *getErrorString(int error);
77 
78  size_t getStride() {
79  return getDepth() * getWidth();
80  };
81 
82  // Accessors for the settings needed by higher level code.
83  // Surface accessors
84  size_t getWidth() {
85  return getWidth(_eglSurface);
86  };
87 
88  size_t getHeight() {
89  return getHeight(_eglSurface);
90  }
91 
92  EGLint getDepth() {
93  EGLint value;
94  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_DEPTH_SIZE, &value);
95  return value;
96  }
97 
98  int getRedSize() {
99  EGLint value;
100  if (_eglConfig && _eglDisplay) {
101  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_RED_SIZE, &value);
102  }
103  return static_cast<int>(value);
104  };
105  int getGreenSize() {
106  EGLint value;
107  if (_eglConfig && _eglDisplay) {
108  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_GREEN_SIZE, &value);
109  }
110  return static_cast<int>(value);
111  };
112  int getBlueSize() {
113  EGLint value;
114  if (_eglConfig && _eglDisplay) {
115  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_BLUE_SIZE, &value);
116  }
117  return static_cast<int>(value);
118  };
119 
121  EGLint value;
122  if (_eglSurface && _eglDisplay) {
123  eglQuerySurface(_eglDisplay, _eglSurface, EGL_RENDER_BUFFER, &value);
124  }
125  if (value == EGL_SINGLE_BUFFER) {
126  return true;
127  }
128  return false;
129  }
131  return isBufferDestroyed(_eglSurface);
132  }
133 
134  int getID() {
135  return static_cast<int>(getSurfaceID());
136  }
137 
138  bool supportsRenderer(GnashDevice::rtype_t rtype);
139 
140  bool isNativeRender() {
141  EGLint value;
142  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_NATIVE_RENDERABLE, &value);
143  return value;
144  }
145 
146  // Overload some of the base class methods to deal with Device specific
147  // data types.
148  bool bindClient(GnashDevice::rtype_t rtype);
149 
150  size_t getWidth(EGLSurface surface) {
151  EGLint value;
152  if (surface && _eglDisplay) {
153  eglQuerySurface(_eglDisplay, surface, EGL_WIDTH, &value);
154  }
155  return static_cast<size_t>(value);
156  };
157  size_t getHeight(EGLSurface surface) {
158  EGLint value;
159  if (surface && _eglDisplay) {
160  eglQuerySurface(_eglDisplay, surface, EGL_HEIGHT, &value);
161  }
162  return static_cast<size_t>(value);
163  }
164  bool isBufferDestroyed(EGLSurface surface) {
165  EGLint value;
166  eglQuerySurface(_eglDisplay, surface, EGL_SWAP_BEHAVIOR, &value);
167  if (value == EGL_BUFFER_DESTROYED) {
168  return true;
169  }
170  return false;
171  }
172 #ifdef BUILD_X11_DEVICE
173  EGLint getNativeVisual();
174 #endif
175 
177  bool checkEGLConfig(EGLConfig config);
178 
180  int queryEGLConfig() { return queryEGLConfig(_eglDisplay); };
181  int queryEGLConfig(EGLDisplay display);
182 
183  // Debugging utilities
184  void printEGLConfig() { return printEGLConfig(_eglConfig); };
185  void printEGLConfig(EGLConfig config);
186  void printEGLContext() { return printEGLContext(_eglContext); };
187  void printEGLContext(EGLContext context);
188  void printEGLSurface() { return printEGLSurface(_eglSurface); };
189  void printEGLSurface(EGLSurface surface);
190  void printEGLAttribs(const EGLint *attrib);
191 
192  // Create Pbuffers for offscreen rendering
193  EGLSurface createPbuffer(int width, int height);
194  EGLSurface createPbuffer(int width, int height, EGLClientBuffer buf, EGLenum type);
195  EGLSurface createPixmap(int width, int height, NativePixmapType buf);
196  size_t totalPbuffers() { return _pbuffers.size(); };
197  EGLSurface &operator[](int index) { if (!_pbuffers.empty()) { return _pbuffers[index]; }; };
198 
199  // Swapping Buffers makes the specified surface active on the display if
200  // EGL_RENDER_BUFFER is set to EGL_BACK_BUFFER. If it's set to
201  // EGL_SINGLE_BUFFER then this has no effect, as the display was drawn to
202  // directly.
203  // Swap to the default surface
204  bool swapBuffers() {
205  // GNASH_REPORT_FUNCTION;
206  if (!isSingleBuffered()) {
207  return eglSwapBuffers(_eglDisplay, _eglSurface);
208  }
209  return true;
210  }
211  bool copyPbuffers(size_t x) {
213  if (x < _pbuffers.size()) {
214  NativePixmapType pix;
215  if (!eglCopyBuffers(_eglDisplay, _pbuffers[x], pix)) {
216  log_error( "eglCopyBuffers() failed (error 0x%x)", eglGetError());
217  return false;
218  }
219  return true;
220  }
221  return false;
222  }
223  // Make one of the pbuffers the current one to draw into
225  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
226  if (!eglMakeCurrent(_eglDisplay, _eglSurface, _eglSurface, _eglContext)) {
227  log_error( "eglMakeCurrent() failed (error 0x%x)", eglGetError());
228  return false;
229  }
230  }
231  return false;
232  }
233 
234  bool makePbufferCurrent(size_t x) {
235  if (x < _pbuffers.size()) {
236  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglContext != EGL_NO_CONTEXT)) {
237  if (!eglMakeCurrent(_eglDisplay, _pbuffers[x], _pbuffers[x], _eglContext)) {
238  log_error( "eglMakeCurrent() failed (error 0x%x)", eglGetError());
239  return false;
240  }
241  return true;
242  }
243  }
244  return false;
245  }
246 
247  size_t getVerticalRes() {
248  EGLint value = 0;
249  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
250  eglQuerySurface(_eglDisplay, _eglSurface, EGL_VERTICAL_RESOLUTION, &value);
251  }
252  return static_cast<size_t>(value);
253  }
254  size_t getHorzRes() {
255  EGLint value = 0;
256  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
257  eglQuerySurface(_eglDisplay, _eglSurface, EGL_HORIZONTAL_RESOLUTION, &value);
258  }
259  return static_cast<size_t>(value);
260  }
261  bool isBackBuffered() {
262  EGLint value;
263  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
264  eglQuerySurface(_eglDisplay, _eglSurface, EGL_RENDER_BUFFER, &value);
265  if (value == EGL_BACK_BUFFER) {
266  return true;
267  }
268  return false;
269  }
270  return false;
271  }
272 
273  bool isMultiSample() {
274  EGLint value;
275  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
276  eglQuerySurface(_eglDisplay, _eglSurface, EGL_MULTISAMPLE_RESOLVE, &value);
277  if (value == EGL_MULTISAMPLE_RESOLVE_BOX) {
278  return true;
279  }
280  return false;
281  }
282  return false;
283  }
284 
285  EGLint getSurfaceID() {
286  EGLint value = -1;
287  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglSurface != EGL_NO_SURFACE)) {
288  eglQuerySurface(_eglDisplay, _eglSurface, EGL_CONFIG_ID, &value);
289  }
290  return value;
291  }
292 
293  // Context accessors
294  EGLint getContextID() {
295  EGLint value = -1;
296  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglContext != EGL_NO_CONTEXT)) {
297  eglQueryContext(_eglDisplay, _eglContext, EGL_CONFIG_ID, &value);
298  }
299  return value;
300  }
302  EGLint value;
303  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglContext != EGL_NO_CONTEXT)) {
304  eglQueryContext(_eglDisplay, _eglContext, EGL_RENDER_BUFFER, &value);
305  if (value == EGL_SINGLE_BUFFER) {
306  return true;
307  }
308  return false;
309  }
310  return false;
311  }
313  EGLint value;
314  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglContext != EGL_NO_CONTEXT)) {
315  eglQueryContext(_eglDisplay, _eglContext, EGL_RENDER_BUFFER, &value);
316  if (value == EGL_BACK_BUFFER) {
317  return true;
318  }
319  return false;
320  }
321  return false;
322  }
323 
324  // Config accessors
325  EGLint getSamples() {
326  EGLint value = -1;
327  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglConfig != 0)) {
328  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_SAMPLES, &value);
329  }
330  return value;
331  }
332  EGLint getSampleBuffers() {
333  EGLint value = -1;
334  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglConfig != 0)) {
335  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_SAMPLE_BUFFERS, &value);
336  }
337  return value;
338  }
340  EGLint value = -1;
341  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglConfig != 0)) {
342  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_MAX_SWAP_INTERVAL, &value);
343  }
344  return value;
345  }
347  EGLint value = -1;
348  if ((_eglDisplay != EGL_NO_DISPLAY) && (_eglConfig != 0)) {
349  eglGetConfigAttrib(_eglDisplay, _eglConfig, EGL_MIN_SWAP_INTERVAL, &value);
350  }
351  return value;
352  }
353 
354  void setAttrib(int bpp);
355  static EGLint getRenderableTypes();
356 protected:
357  EGLConfig _eglConfig;
358  EGLContext _eglContext;
359  EGLSurface _eglSurface;
360  EGLDisplay _eglDisplay;
361  EGLNativeWindowType _nativeWindow;
362  EGLNativePixmapType _nativePixmap;
363  quality_e _quality;
364  const EGLint *_attrib;
365  unsigned int _bpp;
366  std::vector<EGLSurface> _pbuffers;
367 };
368 
369 #define DUMP_CURRENT_SURFACE printEGLSurface(eglGetCurrentSurface(EGL_DRAW))
370 #define DUMP_CURRENT_CONTEXT printEGLContext(eglGetCurrentContext())
371 
372 } // namespace renderer
373 } // namespace gnash
374 
375 #endif // end of __EGL_DEVICE_H__
376 
377 // local Variables:
378 // mode: C++
379 // indent-tabs-mode: nil
380 // End:
bool isContextSingleBuffered()
Definition: eglDevice.h:301
dtype_t getType()
Definition: eglDevice.h:66
EGLint getSurfaceID()
Definition: eglDevice.h:285
void printEGLContext()
Definition: eglDevice.h:186
EGLint getDepth()
Get the depth of the device.
Definition: eglDevice.h:92
bool isContextBackBuffered()
Definition: eglDevice.h:312
bool copyPbuffers(size_t x)
Definition: eglDevice.h:211
EGLContext _eglContext
Definition: eglDevice.h:358
bool makePbufferCurrent(size_t x)
Definition: eglDevice.h:234
size_t totalPbuffers()
Definition: eglDevice.h:196
float _y
Definition: eglDevice.h:53
EGLNativePixmapType _nativePixmap
Definition: eglDevice.h:362
size_t getHeight(EGLSurface surface)
Definition: eglDevice.h:157
EGLint getSampleBuffers()
Definition: eglDevice.h:332
const EGLint * _attrib
Definition: eglDevice.h:364
long native_window_t
Definition: GnashDevice.h:43
bool swapBuffers()
Definition: eglDevice.h:204
bool makePbufferCurrent()
Definition: eglDevice.h:224
EGLSurface & operator[](int index)
Definition: eglDevice.h:197
Definition: GnashDevice.h:39
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:40
dtype_t
The list of supported device types.
Definition: GnashDevice.h:48
Definition: eglDevice.h:46
int getGreenSize()
Get the size of the Green pixel.
Definition: eglDevice.h:105
EGLConfig _eglConfig
Definition: eglDevice.h:357
type
Definition: GnashKey.h:329
bool isSingleBuffered()
Is this device single buffered.
Definition: eglDevice.h:120
void printEGLSurface()
Definition: eglDevice.h:188
Definition: klash_part.cpp:329
2D Point class
Definition: Point2d.h:38
size_t getWidth(EGLSurface surface)
Definition: eglDevice.h:150
eglVertex(const point &p)
Definition: eglDevice.h:50
size_t getStride()
Query the system for all supported configs.
Definition: eglDevice.h:78
bool isBufferDestroyed(EGLSurface surface)
Definition: eglDevice.h:164
int getRedSize()
Get the size of the Red pixel.
Definition: eglDevice.h:98
bool isNativeRender()
Is this renderering natively.
Definition: eglDevice.h:140
EGLint getContextID()
Definition: eglDevice.h:294
quality_e _quality
Definition: eglDevice.h:363
Definition: klash_part.cpp:329
bool isMultiSample()
Definition: eglDevice.h:273
struct lirc_config * config
Definition: lirc_ext.cpp:43
int getBlueSize()
Get the size of the Blue pixel.
Definition: eglDevice.h:112
size_t getHeight()
Get the Height of the device.
Definition: eglDevice.h:88
rtype_t
The list of supported renders that use devices.
Definition: GnashDevice.h:46
void log_error(StringType msg, Args... args)
Definition: log.h:283
bool isBackBuffered()
Definition: eglDevice.h:261
void printEGLConfig()
Definition: eglDevice.h:184
int queryEGLConfig()
Query the system for all supported configs.
Definition: eglDevice.h:180
EGLNativeWindowType _nativeWindow
Definition: eglDevice.h:361
std::vector< EGLSurface > _pbuffers
Definition: eglDevice.h:366
EGLint getMinSwapInterval()
Definition: eglDevice.h:346
std::int32_t x
Definition: BitmapData_as.cpp:434
BitmapData_as::iterator pix
Definition: BitmapData_as.cpp:568
EGLint getSamples()
Definition: eglDevice.h:325
Definition: eglDevice.h:56
eglVertex(float x, float y)
Definition: eglDevice.h:47
unsigned int _bpp
Definition: eglDevice.h:365
std::int32_t y
Definition: BitmapData_as.cpp:435
EGLDisplay _eglDisplay
Definition: eglDevice.h:360
Definition: GnashKey.h:162
#define GNASH_REPORT_FUNCTION
Definition: log.h:452
quality_e
Definition: eglDevice.h:59
bool isBufferDestroyed()
Are buffers destroyed ?
Definition: eglDevice.h:130
int getID()
Get the window ID handle.
Definition: eglDevice.h:134
size_t getVerticalRes()
Definition: eglDevice.h:247
as_value getHeight(DisplayObject &o)
Definition: DisplayObject.cpp:356
EGLSurface _eglSurface
Definition: eglDevice.h:359
EGLint getMaxSwapInterval()
Definition: eglDevice.h:339
size_t getHorzRes()
Definition: eglDevice.h:254
float _x
Definition: eglDevice.h:52
size_t getWidth()
Get the width of the device.
Definition: eglDevice.h:84