NativeWindowEglFbdev.cpp 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. #include "anki/core/NativeWindowEglFbdev.h"
  2. #include "anki/util/Exception.h"
  3. #include "anki/util/Vector.h"
  4. #include "anki/util/Array.h"
  5. #include "anki/util/StdTypes.h"
  6. namespace anki {
  7. //==============================================================================
  8. // NativeWindowImpl =
  9. //==============================================================================
  10. //==============================================================================
  11. void NativeWindowImpl::create(NativeWindowInitializer& init)
  12. {
  13. // Create window
  14. //
  15. fbwin = (fbdev_window*)malloc(sizeof(fbdev_window));
  16. if(fbwin == NULL)
  17. {
  18. throw ANKI_EXCEPTION("malloc() failed");
  19. }
  20. fbwin->width = init.width;
  21. fbwin->height = init.height;
  22. // EGL init
  23. //
  24. display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  25. if(display == EGL_NO_DISPLAY)
  26. {
  27. throw ANKI_EXCEPTION("Failed to create display");
  28. }
  29. int major, minor;
  30. if(eglInitialize(display, &major, &minor) == EGL_FALSE)
  31. {
  32. throw ANKI_EXCEPTION("Failed to initialize EGL");
  33. }
  34. int maxConfigs;
  35. if(eglGetConfigs(display, NULL, 0, &maxConfigs) == EGL_FALSE)
  36. {
  37. throw ANKI_EXCEPTION("Failed to query EGL configs");
  38. }
  39. if(maxConfigs < 1)
  40. {
  41. throw ANKI_EXCEPTION("Error in number of configs");
  42. }
  43. Vector<EGLConfig> configs(maxConfigs);
  44. Array<EGLint, 256> attribs;
  45. U attr = 0;
  46. attribs[attr++] = EGL_RENDERABLE_TYPE;
  47. attribs[attr++] = EGL_OPENGL_ES2_BIT;
  48. if(init.samplesCount > 1)
  49. {
  50. attribs[attr++] = EGL_SAMPLES;
  51. attribs[attr++] = init.samplesCount;
  52. }
  53. attribs[attr++] = EGL_RED_SIZE;
  54. attribs[attr++] = init.rgbaBits[0];
  55. attribs[attr++] = EGL_GREEN_SIZE;
  56. attribs[attr++] = init.rgbaBits[1];
  57. attribs[attr++] = EGL_BLUE_SIZE;
  58. attribs[attr++] = init.rgbaBits[2];
  59. attribs[attr++] = EGL_ALPHA_SIZE;
  60. attribs[attr++] = init.rgbaBits[3];
  61. attribs[attr++] = EGL_DEPTH_SIZE;
  62. attribs[attr++] = init.depthBits;
  63. attribs[attr++] = EGL_STENCIL_SIZE;
  64. attribs[attr++] = init.stencilBits;
  65. attribs[attr++] = EGL_NONE;
  66. EGLint configsCount;
  67. if(eglChooseConfig(display, &attribs[0], &configs[0], maxConfigs,
  68. &configsCount) == EGL_FALSE)
  69. {
  70. throw ANKI_EXCEPTION("Failed to query required EGL configs");
  71. }
  72. if(configsCount == 0)
  73. {
  74. throw ANKI_EXCEPTION("No matching EGL configs found");
  75. }
  76. EGLConfig config_ = nullptr;
  77. for(EGLint i = 0; i < configsCount; i++)
  78. {
  79. EGLint value;
  80. EGLConfig config = configs[i];
  81. // Use this to explicitly check that the EGL config has the
  82. // expected color depths
  83. eglGetConfigAttrib(display, config, EGL_RED_SIZE, &value);
  84. if(value != (EGLint)init.rgbaBits[0])
  85. {
  86. continue;
  87. }
  88. eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &value);
  89. if(value != (EGLint)init.rgbaBits[1])
  90. {
  91. continue;
  92. }
  93. eglGetConfigAttrib(display, config, EGL_BLUE_SIZE, &value);
  94. if(value != (EGLint)init.rgbaBits[2])
  95. {
  96. continue;
  97. }
  98. eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &value);
  99. if(value != (EGLint)init.rgbaBits[3])
  100. {
  101. continue;
  102. }
  103. eglGetConfigAttrib(display, config, EGL_SAMPLES, &value);
  104. if(value != (EGLint)init.samplesCount)
  105. {
  106. continue;
  107. }
  108. eglGetConfigAttrib(display, config, EGL_DEPTH_SIZE, &value);
  109. if(value != (EGLint)init.depthBits)
  110. {
  111. continue;
  112. }
  113. eglGetConfigAttrib(display, config, EGL_STENCIL_SIZE, &value);
  114. if(value != (EGLint)init.stencilBits)
  115. {
  116. continue;
  117. }
  118. // We found what we wanted
  119. config_ = config;
  120. break;
  121. }
  122. if(config_ == nullptr)
  123. {
  124. throw ANKI_EXCEPTION("Unable to find suitable EGL config");
  125. }
  126. // Surface
  127. //
  128. surface = eglCreateWindowSurface(display, config_,
  129. static_cast<EGLNativeWindowType>(fbwin), NULL);
  130. if(surface == EGL_NO_SURFACE)
  131. {
  132. throw ANKI_EXCEPTION("Cannot create surface");
  133. }
  134. // Context
  135. //
  136. EGLint ctxAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
  137. context = eglCreateContext(display, config_, EGL_NO_CONTEXT,
  138. ctxAttribs);
  139. if(context == EGL_NO_CONTEXT)
  140. {
  141. throw ANKI_EXCEPTION("Cannot create context");
  142. }
  143. if(eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
  144. {
  145. throw ANKI_EXCEPTION("Cannot make the context current");
  146. }
  147. }
  148. //==============================================================================
  149. void NativeWindowImpl::destroy()
  150. {
  151. // XXX
  152. }
  153. //==============================================================================
  154. // NativeWindow =
  155. //==============================================================================
  156. //==============================================================================
  157. NativeWindow::~NativeWindow()
  158. {}
  159. //==============================================================================
  160. void NativeWindow::create(NativeWindowInitializer& initializer)
  161. {
  162. impl.reset(new NativeWindowImpl);
  163. impl->create(initializer);
  164. }
  165. //==============================================================================
  166. void NativeWindow::destroy()
  167. {
  168. impl.reset();
  169. }
  170. //==============================================================================
  171. void NativeWindow::swapBuffers()
  172. {
  173. ANKI_ASSERT(isCreated());
  174. if(eglSwapBuffers(impl->display, impl->surface) == EGL_FALSE)
  175. {
  176. throw ANKI_EXCEPTION("eglSwapBuffers() failed");
  177. }
  178. }
  179. } // end namespace anki