PageRenderTime 57ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 1ms

/lib_angle/src/libGLESv2/entry_points_egl.cpp

https://bitbucket.org/xixs/lua
C++ | 1236 lines | 983 code | 235 blank | 18 comment | 166 complexity | 95c2c89a5bc442ca29aeb4263e78e569 MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, CC0-1.0, GPL-3.0, GPL-2.0, CPL-1.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, LGPL-2.1, LGPL-3.0, 0BSD, Cube
  1. //
  2. // Copyright(c) 2014 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. // entry_points_egl.cpp : Implements the EGL entry points.
  7. #include "libGLESv2/entry_points_egl.h"
  8. #include "libGLESv2/entry_points_egl_ext.h"
  9. #include "libGLESv2/entry_points_gles_2_0_ext.h"
  10. #include "libGLESv2/entry_points_gles_3_0_ext.h"
  11. #include "libGLESv2/global_state.h"
  12. #include "libANGLE/Context.h"
  13. #include "libANGLE/Display.h"
  14. #include "libANGLE/Texture.h"
  15. #include "libANGLE/Surface.h"
  16. #include "common/debug.h"
  17. #include "common/version.h"
  18. #include <EGL/eglext.h>
  19. namespace egl
  20. {
  21. // EGL object validation
  22. static bool ValidateDisplay(Display *display)
  23. {
  24. if (display == EGL_NO_DISPLAY)
  25. {
  26. SetGlobalError(Error(EGL_BAD_DISPLAY));
  27. return false;
  28. }
  29. if (!display->isInitialized())
  30. {
  31. SetGlobalError(Error(EGL_NOT_INITIALIZED));
  32. return false;
  33. }
  34. return true;
  35. }
  36. static bool ValidateConfig(Display *display, EGLConfig config)
  37. {
  38. if (!ValidateDisplay(display))
  39. {
  40. return false;
  41. }
  42. if (!display->isValidConfig(config))
  43. {
  44. SetGlobalError(Error(EGL_BAD_CONFIG));
  45. return false;
  46. }
  47. return true;
  48. }
  49. static bool ValidateContext(Display *display, gl::Context *context)
  50. {
  51. if (!ValidateDisplay(display))
  52. {
  53. return false;
  54. }
  55. if (!display->isValidContext(context))
  56. {
  57. SetGlobalError(Error(EGL_BAD_CONTEXT));
  58. return false;
  59. }
  60. return true;
  61. }
  62. static bool ValidateSurface(Display *display, Surface *surface)
  63. {
  64. if (!ValidateDisplay(display))
  65. {
  66. return false;
  67. }
  68. if (!display->isValidSurface(surface))
  69. {
  70. SetGlobalError(Error(EGL_BAD_SURFACE));
  71. return false;
  72. }
  73. return true;
  74. }
  75. // EGL 1.0
  76. EGLint EGLAPIENTRY GetError(void)
  77. {
  78. EVENT("()");
  79. EGLint error = GetGlobalError();
  80. SetGlobalError(Error(EGL_SUCCESS));
  81. return error;
  82. }
  83. EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id)
  84. {
  85. EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
  86. return Display::getDisplay(display_id, AttributeMap());
  87. }
  88. EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
  89. {
  90. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)",
  91. dpy, major, minor);
  92. if (dpy == EGL_NO_DISPLAY)
  93. {
  94. SetGlobalError(Error(EGL_BAD_DISPLAY));
  95. return EGL_FALSE;
  96. }
  97. Display *display = static_cast<Display*>(dpy);
  98. Error error = display->initialize();
  99. if (error.isError())
  100. {
  101. SetGlobalError(error);
  102. return EGL_FALSE;
  103. }
  104. if (major) *major = 1;
  105. if (minor) *minor = 4;
  106. SetGlobalError(Error(EGL_SUCCESS));
  107. return EGL_TRUE;
  108. }
  109. EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy)
  110. {
  111. EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
  112. if (dpy == EGL_NO_DISPLAY)
  113. {
  114. SetGlobalError(Error(EGL_BAD_DISPLAY));
  115. return EGL_FALSE;
  116. }
  117. Display *display = static_cast<Display*>(dpy);
  118. gl::Context *context = GetGlobalContext();
  119. if (display->isValidContext(context))
  120. {
  121. SetGlobalContext(NULL);
  122. SetGlobalDisplay(NULL);
  123. }
  124. display->terminate();
  125. SetGlobalError(Error(EGL_SUCCESS));
  126. return EGL_TRUE;
  127. }
  128. const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
  129. {
  130. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
  131. Display *display = static_cast<Display*>(dpy);
  132. if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS) && !ValidateDisplay(display))
  133. {
  134. return NULL;
  135. }
  136. const char *result;
  137. switch (name)
  138. {
  139. case EGL_CLIENT_APIS:
  140. result = "OpenGL_ES";
  141. break;
  142. case EGL_EXTENSIONS:
  143. if (display == EGL_NO_DISPLAY)
  144. {
  145. result = Display::getClientExtensionString().c_str();
  146. }
  147. else
  148. {
  149. result = display->getExtensionString().c_str();
  150. }
  151. break;
  152. case EGL_VENDOR:
  153. result = display->getVendorString().c_str();
  154. break;
  155. case EGL_VERSION:
  156. result = "1.4 (ANGLE " ANGLE_VERSION_STRING ")";
  157. break;
  158. default:
  159. SetGlobalError(Error(EGL_BAD_PARAMETER));
  160. return NULL;
  161. }
  162. SetGlobalError(Error(EGL_SUCCESS));
  163. return result;
  164. }
  165. EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
  166. {
  167. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
  168. "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
  169. dpy, configs, config_size, num_config);
  170. Display *display = static_cast<Display*>(dpy);
  171. if (!ValidateDisplay(display))
  172. {
  173. return EGL_FALSE;
  174. }
  175. if (!num_config)
  176. {
  177. SetGlobalError(Error(EGL_BAD_PARAMETER));
  178. return EGL_FALSE;
  179. }
  180. const EGLint attribList[] = {EGL_NONE};
  181. if (!display->getConfigs(configs, attribList, config_size, num_config))
  182. {
  183. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  184. return EGL_FALSE;
  185. }
  186. SetGlobalError(Error(EGL_SUCCESS));
  187. return EGL_TRUE;
  188. }
  189. EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
  190. {
  191. EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
  192. "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
  193. dpy, attrib_list, configs, config_size, num_config);
  194. Display *display = static_cast<Display*>(dpy);
  195. if (!ValidateDisplay(display))
  196. {
  197. return EGL_FALSE;
  198. }
  199. if (!num_config)
  200. {
  201. SetGlobalError(Error(EGL_BAD_PARAMETER));
  202. return EGL_FALSE;
  203. }
  204. const EGLint attribList[] = {EGL_NONE};
  205. if (!attrib_list)
  206. {
  207. attrib_list = attribList;
  208. }
  209. display->getConfigs(configs, attrib_list, config_size, num_config);
  210. SetGlobalError(Error(EGL_SUCCESS));
  211. return EGL_TRUE;
  212. }
  213. EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
  214. {
  215. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
  216. dpy, config, attribute, value);
  217. Display *display = static_cast<Display*>(dpy);
  218. if (!ValidateConfig(display, config))
  219. {
  220. return EGL_FALSE;
  221. }
  222. if (!display->getConfigAttrib(config, attribute, value))
  223. {
  224. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  225. return EGL_FALSE;
  226. }
  227. SetGlobalError(Error(EGL_SUCCESS));
  228. return EGL_TRUE;
  229. }
  230. EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
  231. {
  232. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
  233. "const EGLint *attrib_list = 0x%0.8p)", dpy, config, win, attrib_list);
  234. Display *display = static_cast<Display*>(dpy);
  235. if (!ValidateConfig(display, config))
  236. {
  237. return EGL_NO_SURFACE;
  238. }
  239. if (!display->isValidNativeWindow(win))
  240. {
  241. SetGlobalError(Error(EGL_BAD_NATIVE_WINDOW));
  242. return EGL_NO_SURFACE;
  243. }
  244. EGLSurface surface = EGL_NO_SURFACE;
  245. Error error = display->createWindowSurface(win, config, attrib_list, &surface);
  246. if (error.isError())
  247. {
  248. SetGlobalError(error);
  249. return EGL_NO_SURFACE;
  250. }
  251. return surface;
  252. }
  253. EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
  254. {
  255. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
  256. dpy, config, attrib_list);
  257. Display *display = static_cast<Display*>(dpy);
  258. if (!ValidateConfig(display, config))
  259. {
  260. return EGL_NO_SURFACE;
  261. }
  262. EGLSurface surface = EGL_NO_SURFACE;
  263. Error error = display->createOffscreenSurface(config, NULL, attrib_list, &surface);
  264. if (error.isError())
  265. {
  266. SetGlobalError(error);
  267. return EGL_NO_SURFACE;
  268. }
  269. return surface;
  270. }
  271. EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
  272. {
  273. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
  274. "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
  275. Display *display = static_cast<Display*>(dpy);
  276. if (!ValidateConfig(display, config))
  277. {
  278. return EGL_NO_SURFACE;
  279. }
  280. UNIMPLEMENTED(); // FIXME
  281. SetGlobalError(Error(EGL_SUCCESS));
  282. return EGL_NO_SURFACE;
  283. }
  284. EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
  285. {
  286. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
  287. Display *display = static_cast<Display*>(dpy);
  288. Surface *eglSurface = static_cast<Surface*>(surface);
  289. if (!ValidateSurface(display, eglSurface))
  290. {
  291. return EGL_FALSE;
  292. }
  293. if (surface == EGL_NO_SURFACE)
  294. {
  295. SetGlobalError(Error(EGL_BAD_SURFACE));
  296. return EGL_FALSE;
  297. }
  298. display->destroySurface((Surface*)surface);
  299. SetGlobalError(Error(EGL_SUCCESS));
  300. return EGL_TRUE;
  301. }
  302. EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
  303. {
  304. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
  305. dpy, surface, attribute, value);
  306. Display *display = static_cast<Display*>(dpy);
  307. Surface *eglSurface = (Surface*)surface;
  308. if (!ValidateSurface(display, eglSurface))
  309. {
  310. return EGL_FALSE;
  311. }
  312. if (surface == EGL_NO_SURFACE)
  313. {
  314. SetGlobalError(Error(EGL_BAD_SURFACE));
  315. return EGL_FALSE;
  316. }
  317. switch (attribute)
  318. {
  319. case EGL_VG_ALPHA_FORMAT:
  320. UNIMPLEMENTED(); // FIXME
  321. break;
  322. case EGL_VG_COLORSPACE:
  323. UNIMPLEMENTED(); // FIXME
  324. break;
  325. case EGL_CONFIG_ID:
  326. *value = eglSurface->getConfigID();
  327. break;
  328. case EGL_HEIGHT:
  329. *value = eglSurface->getHeight();
  330. break;
  331. case EGL_HORIZONTAL_RESOLUTION:
  332. UNIMPLEMENTED(); // FIXME
  333. break;
  334. case EGL_LARGEST_PBUFFER:
  335. UNIMPLEMENTED(); // FIXME
  336. break;
  337. case EGL_MIPMAP_TEXTURE:
  338. UNIMPLEMENTED(); // FIXME
  339. break;
  340. case EGL_MIPMAP_LEVEL:
  341. UNIMPLEMENTED(); // FIXME
  342. break;
  343. case EGL_MULTISAMPLE_RESOLVE:
  344. UNIMPLEMENTED(); // FIXME
  345. break;
  346. case EGL_PIXEL_ASPECT_RATIO:
  347. *value = eglSurface->getPixelAspectRatio();
  348. break;
  349. case EGL_RENDER_BUFFER:
  350. *value = eglSurface->getRenderBuffer();
  351. break;
  352. case EGL_SWAP_BEHAVIOR:
  353. *value = eglSurface->getSwapBehavior();
  354. break;
  355. case EGL_TEXTURE_FORMAT:
  356. *value = eglSurface->getTextureFormat();
  357. break;
  358. case EGL_TEXTURE_TARGET:
  359. *value = eglSurface->getTextureTarget();
  360. break;
  361. case EGL_VERTICAL_RESOLUTION:
  362. UNIMPLEMENTED(); // FIXME
  363. break;
  364. case EGL_WIDTH:
  365. *value = eglSurface->getWidth();
  366. break;
  367. case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
  368. if (!display->getExtensions().postSubBuffer)
  369. {
  370. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  371. return EGL_FALSE;
  372. }
  373. *value = eglSurface->isPostSubBufferSupported();
  374. break;
  375. case EGL_FIXED_SIZE_ANGLE:
  376. if (!display->getExtensions().windowFixedSize)
  377. {
  378. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  379. return EGL_FALSE;
  380. }
  381. *value = eglSurface->isFixedSize();
  382. break;
  383. default:
  384. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  385. return EGL_FALSE;
  386. }
  387. SetGlobalError(Error(EGL_SUCCESS));
  388. return EGL_TRUE;
  389. }
  390. EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
  391. {
  392. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
  393. "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
  394. Display *display = static_cast<Display*>(dpy);
  395. if (!ValidateDisplay(display))
  396. {
  397. return EGL_NO_CONTEXT;
  398. }
  399. // Get the requested client version (default is 1) and check it is 2 or 3.
  400. EGLint clientMajorVersion = 1;
  401. EGLint clientMinorVersion = 0;
  402. EGLint contextFlags = 0;
  403. bool resetNotification = false;
  404. bool robustAccess = false;
  405. if (attrib_list)
  406. {
  407. for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2)
  408. {
  409. switch (attribute[0])
  410. {
  411. case EGL_CONTEXT_CLIENT_VERSION:
  412. clientMajorVersion = attribute[1];
  413. break;
  414. case EGL_CONTEXT_MINOR_VERSION:
  415. clientMinorVersion = attribute[1];
  416. break;
  417. case EGL_CONTEXT_FLAGS_KHR:
  418. contextFlags = attribute[1];
  419. break;
  420. case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR:
  421. // Only valid for OpenGL (non-ES) contexts
  422. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  423. return EGL_NO_CONTEXT;
  424. case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT:
  425. if (!display->getExtensions().createContextRobustness)
  426. {
  427. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  428. return EGL_NO_CONTEXT;
  429. }
  430. if (attribute[1] != EGL_TRUE && attribute[1] != EGL_FALSE)
  431. {
  432. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  433. return EGL_NO_CONTEXT;
  434. }
  435. robustAccess = (attribute[1] == EGL_TRUE);
  436. break;
  437. case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR:
  438. META_ASSERT(EGL_LOSE_CONTEXT_ON_RESET_EXT == EGL_LOSE_CONTEXT_ON_RESET_KHR);
  439. META_ASSERT(EGL_NO_RESET_NOTIFICATION_EXT == EGL_NO_RESET_NOTIFICATION_KHR);
  440. // same as EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT, fall through
  441. case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT:
  442. if (!display->getExtensions().createContextRobustness)
  443. {
  444. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  445. return EGL_NO_CONTEXT;
  446. }
  447. if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT)
  448. {
  449. resetNotification = true;
  450. }
  451. else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT)
  452. {
  453. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  454. return EGL_NO_CONTEXT;
  455. }
  456. break;
  457. default:
  458. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  459. return EGL_NO_CONTEXT;
  460. }
  461. }
  462. }
  463. if ((clientMajorVersion != 2 && clientMajorVersion != 3) || clientMinorVersion != 0)
  464. {
  465. SetGlobalError(Error(EGL_BAD_CONFIG));
  466. return EGL_NO_CONTEXT;
  467. }
  468. // Note: EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR does not apply to ES
  469. const EGLint validContextFlags = (EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR |
  470. EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR);
  471. if ((contextFlags & ~validContextFlags) != 0)
  472. {
  473. SetGlobalError(Error(EGL_BAD_ATTRIBUTE));
  474. return EGL_NO_CONTEXT;
  475. }
  476. if ((contextFlags & EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR) > 0)
  477. {
  478. robustAccess = true;
  479. }
  480. if (robustAccess)
  481. {
  482. // Unimplemented
  483. SetGlobalError(Error(EGL_BAD_CONFIG));
  484. return EGL_NO_CONTEXT;
  485. }
  486. if (share_context)
  487. {
  488. gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
  489. if (sharedGLContext->isResetNotificationEnabled() != resetNotification)
  490. {
  491. SetGlobalError(Error(EGL_BAD_MATCH));
  492. return EGL_NO_CONTEXT;
  493. }
  494. if (sharedGLContext->getClientVersion() != clientMajorVersion)
  495. {
  496. SetGlobalError(Error(EGL_BAD_CONTEXT));
  497. return EGL_NO_CONTEXT;
  498. }
  499. // Can not share contexts between displays
  500. if (sharedGLContext->getRenderer() != display->getRenderer())
  501. {
  502. SetGlobalError(Error(EGL_BAD_MATCH));
  503. return EGL_NO_CONTEXT;
  504. }
  505. }
  506. if (!ValidateConfig(display, config))
  507. {
  508. return EGL_NO_CONTEXT;
  509. }
  510. EGLContext context = EGL_NO_CONTEXT;
  511. Error error = display->createContext(config, clientMajorVersion, static_cast<gl::Context*>(share_context),
  512. resetNotification, robustAccess, &context);
  513. if (error.isError())
  514. {
  515. SetGlobalError(error);
  516. return EGL_NO_CONTEXT;
  517. }
  518. return context;
  519. }
  520. EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
  521. {
  522. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
  523. Display *display = static_cast<Display*>(dpy);
  524. gl::Context *context = static_cast<gl::Context*>(ctx);
  525. if (!ValidateContext(display, context))
  526. {
  527. return EGL_FALSE;
  528. }
  529. if (ctx == EGL_NO_CONTEXT)
  530. {
  531. SetGlobalError(Error(EGL_BAD_CONTEXT));
  532. return EGL_FALSE;
  533. }
  534. if (context == GetGlobalContext())
  535. {
  536. SetGlobalDisplay(NULL);
  537. SetGlobalContext(NULL);
  538. }
  539. display->destroyContext(context);
  540. SetGlobalError(Error(EGL_SUCCESS));
  541. return EGL_TRUE;
  542. }
  543. EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
  544. {
  545. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
  546. dpy, draw, read, ctx);
  547. Display *display = static_cast<Display*>(dpy);
  548. gl::Context *context = static_cast<gl::Context*>(ctx);
  549. bool noContext = (ctx == EGL_NO_CONTEXT);
  550. bool noSurface = (draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE);
  551. if (noContext != noSurface)
  552. {
  553. SetGlobalError(Error(EGL_BAD_MATCH));
  554. return EGL_FALSE;
  555. }
  556. if (ctx != EGL_NO_CONTEXT && !ValidateContext(display, context))
  557. {
  558. return EGL_FALSE;
  559. }
  560. if (dpy != EGL_NO_DISPLAY && display->isInitialized())
  561. {
  562. rx::Renderer *renderer = display->getRenderer();
  563. if (renderer->testDeviceLost())
  564. {
  565. display->notifyDeviceLost();
  566. return EGL_FALSE;
  567. }
  568. if (renderer->isDeviceLost())
  569. {
  570. SetGlobalError(Error(EGL_CONTEXT_LOST));
  571. return EGL_FALSE;
  572. }
  573. }
  574. Surface *drawSurface = static_cast<Surface*>(draw);
  575. Surface *readSurface = static_cast<Surface*>(read);
  576. if ((draw != EGL_NO_SURFACE && !ValidateSurface(display, drawSurface)) ||
  577. (read != EGL_NO_SURFACE && !ValidateSurface(display, readSurface)))
  578. {
  579. return EGL_FALSE;
  580. }
  581. if (draw != read)
  582. {
  583. UNIMPLEMENTED(); // FIXME
  584. }
  585. SetGlobalDisplay(display);
  586. SetGlobalDrawSurface(drawSurface);
  587. SetGlobalReadSurface(readSurface);
  588. SetGlobalContext(context);
  589. if (context != nullptr && display != nullptr && drawSurface != nullptr)
  590. {
  591. context->makeCurrent(drawSurface);
  592. }
  593. SetGlobalError(Error(EGL_SUCCESS));
  594. return EGL_TRUE;
  595. }
  596. EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
  597. {
  598. EVENT("(EGLint readdraw = %d)", readdraw);
  599. if (readdraw == EGL_READ)
  600. {
  601. SetGlobalError(Error(EGL_SUCCESS));
  602. return GetGlobalReadSurface();
  603. }
  604. else if (readdraw == EGL_DRAW)
  605. {
  606. SetGlobalError(Error(EGL_SUCCESS));
  607. return GetGlobalDrawSurface();
  608. }
  609. else
  610. {
  611. SetGlobalError(Error(EGL_BAD_PARAMETER));
  612. return EGL_NO_SURFACE;
  613. }
  614. }
  615. EGLDisplay EGLAPIENTRY GetCurrentDisplay(void)
  616. {
  617. EVENT("()");
  618. EGLDisplay dpy = GetGlobalDisplay();
  619. SetGlobalError(Error(EGL_SUCCESS));
  620. return dpy;
  621. }
  622. EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
  623. {
  624. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
  625. dpy, ctx, attribute, value);
  626. Display *display = static_cast<Display*>(dpy);
  627. gl::Context *context = static_cast<gl::Context*>(ctx);
  628. if (!ValidateContext(display, context))
  629. {
  630. return EGL_FALSE;
  631. }
  632. UNIMPLEMENTED(); // FIXME
  633. SetGlobalError(Error(EGL_SUCCESS));
  634. return 0;
  635. }
  636. EGLBoolean EGLAPIENTRY WaitGL(void)
  637. {
  638. EVENT("()");
  639. UNIMPLEMENTED(); // FIXME
  640. SetGlobalError(Error(EGL_SUCCESS));
  641. return 0;
  642. }
  643. EGLBoolean EGLAPIENTRY WaitNative(EGLint engine)
  644. {
  645. EVENT("(EGLint engine = %d)", engine);
  646. UNIMPLEMENTED(); // FIXME
  647. SetGlobalError(Error(EGL_SUCCESS));
  648. return 0;
  649. }
  650. EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
  651. {
  652. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
  653. Display *display = static_cast<Display*>(dpy);
  654. Surface *eglSurface = (Surface*)surface;
  655. if (!ValidateSurface(display, eglSurface))
  656. {
  657. return EGL_FALSE;
  658. }
  659. if (display->getRenderer()->isDeviceLost())
  660. {
  661. SetGlobalError(Error(EGL_CONTEXT_LOST));
  662. return EGL_FALSE;
  663. }
  664. if (surface == EGL_NO_SURFACE)
  665. {
  666. SetGlobalError(Error(EGL_BAD_SURFACE));
  667. return EGL_FALSE;
  668. }
  669. Error error = eglSurface->swap();
  670. if (error.isError())
  671. {
  672. SetGlobalError(error);
  673. return EGL_FALSE;
  674. }
  675. SetGlobalError(Error(EGL_SUCCESS));
  676. return EGL_TRUE;
  677. }
  678. EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
  679. {
  680. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
  681. Display *display = static_cast<Display*>(dpy);
  682. Surface *eglSurface = static_cast<Surface*>(surface);
  683. if (!ValidateSurface(display, eglSurface))
  684. {
  685. return EGL_FALSE;
  686. }
  687. if (display->getRenderer()->isDeviceLost())
  688. {
  689. SetGlobalError(Error(EGL_CONTEXT_LOST));
  690. return EGL_FALSE;
  691. }
  692. UNIMPLEMENTED(); // FIXME
  693. SetGlobalError(Error(EGL_SUCCESS));
  694. return 0;
  695. }
  696. // EGL 1.1
  697. EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  698. {
  699. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
  700. Display *display = static_cast<Display*>(dpy);
  701. Surface *eglSurface = static_cast<Surface*>(surface);
  702. if (!ValidateSurface(display, eglSurface))
  703. {
  704. return EGL_FALSE;
  705. }
  706. if (buffer != EGL_BACK_BUFFER)
  707. {
  708. SetGlobalError(Error(EGL_BAD_PARAMETER));
  709. return EGL_FALSE;
  710. }
  711. if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
  712. {
  713. SetGlobalError(Error(EGL_BAD_SURFACE));
  714. return EGL_FALSE;
  715. }
  716. if (eglSurface->getBoundTexture())
  717. {
  718. SetGlobalError(Error(EGL_BAD_ACCESS));
  719. return EGL_FALSE;
  720. }
  721. if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
  722. {
  723. SetGlobalError(Error(EGL_BAD_MATCH));
  724. return EGL_FALSE;
  725. }
  726. gl::Context *context = GetGlobalContext();
  727. if (context)
  728. {
  729. gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
  730. ASSERT(textureObject != NULL);
  731. if (textureObject->isImmutable())
  732. {
  733. SetGlobalError(Error(EGL_BAD_MATCH));
  734. return EGL_FALSE;
  735. }
  736. eglSurface->bindTexImage(textureObject, buffer);
  737. }
  738. SetGlobalError(Error(EGL_SUCCESS));
  739. return EGL_TRUE;
  740. }
  741. EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
  742. {
  743. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
  744. dpy, surface, attribute, value);
  745. Display *display = static_cast<Display*>(dpy);
  746. Surface *eglSurface = static_cast<Surface*>(surface);
  747. if (!ValidateSurface(display, eglSurface))
  748. {
  749. return EGL_FALSE;
  750. }
  751. UNIMPLEMENTED(); // FIXME
  752. SetGlobalError(Error(EGL_SUCCESS));
  753. return EGL_TRUE;
  754. }
  755. EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
  756. {
  757. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
  758. Display *display = static_cast<Display*>(dpy);
  759. Surface *eglSurface = static_cast<Surface*>(surface);
  760. if (!ValidateSurface(display, eglSurface))
  761. {
  762. return EGL_FALSE;
  763. }
  764. if (buffer != EGL_BACK_BUFFER)
  765. {
  766. SetGlobalError(Error(EGL_BAD_PARAMETER));
  767. return EGL_FALSE;
  768. }
  769. if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle())
  770. {
  771. SetGlobalError(Error(EGL_BAD_SURFACE));
  772. return EGL_FALSE;
  773. }
  774. if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
  775. {
  776. SetGlobalError(Error(EGL_BAD_MATCH));
  777. return EGL_FALSE;
  778. }
  779. gl::Texture *texture = eglSurface->getBoundTexture();
  780. if (texture)
  781. {
  782. eglSurface->releaseTexImage(buffer);
  783. }
  784. SetGlobalError(Error(EGL_SUCCESS));
  785. return EGL_TRUE;
  786. }
  787. EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
  788. {
  789. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
  790. Display *display = static_cast<Display*>(dpy);
  791. if (!ValidateDisplay(display))
  792. {
  793. return EGL_FALSE;
  794. }
  795. Surface *draw_surface = static_cast<Surface*>(GetGlobalDrawSurface());
  796. if (draw_surface == NULL)
  797. {
  798. SetGlobalError(Error(EGL_BAD_SURFACE));
  799. return EGL_FALSE;
  800. }
  801. draw_surface->setSwapInterval(interval);
  802. SetGlobalError(Error(EGL_SUCCESS));
  803. return EGL_TRUE;
  804. }
  805. // EGL 1.2
  806. EGLBoolean EGLAPIENTRY BindAPI(EGLenum api)
  807. {
  808. EVENT("(EGLenum api = 0x%X)", api);
  809. switch (api)
  810. {
  811. case EGL_OPENGL_API:
  812. case EGL_OPENVG_API:
  813. SetGlobalError(Error(EGL_BAD_PARAMETER));
  814. return EGL_FALSE; // Not supported by this implementation
  815. case EGL_OPENGL_ES_API:
  816. break;
  817. default:
  818. SetGlobalError(Error(EGL_BAD_PARAMETER));
  819. return EGL_FALSE;
  820. }
  821. SetGlobalAPI(api);
  822. SetGlobalError(Error(EGL_SUCCESS));
  823. return EGL_TRUE;
  824. }
  825. EGLenum EGLAPIENTRY QueryAPI(void)
  826. {
  827. EVENT("()");
  828. EGLenum API = GetGlobalAPI();
  829. SetGlobalError(Error(EGL_SUCCESS));
  830. return API;
  831. }
  832. EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
  833. {
  834. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
  835. "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
  836. dpy, buftype, buffer, config, attrib_list);
  837. Display *display = static_cast<Display*>(dpy);
  838. if (!ValidateConfig(display, config))
  839. {
  840. return EGL_NO_SURFACE;
  841. }
  842. if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer)
  843. {
  844. SetGlobalError(Error(EGL_BAD_PARAMETER));
  845. return EGL_NO_SURFACE;
  846. }
  847. EGLSurface surface = EGL_NO_SURFACE;
  848. Error error = display->createOffscreenSurface(config, buffer, attrib_list, &surface);
  849. if (error.isError())
  850. {
  851. SetGlobalError(error);
  852. return EGL_NO_SURFACE;
  853. }
  854. return surface;
  855. }
  856. EGLBoolean EGLAPIENTRY ReleaseThread(void)
  857. {
  858. EVENT("()");
  859. MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
  860. SetGlobalError(Error(EGL_SUCCESS));
  861. return EGL_TRUE;
  862. }
  863. EGLBoolean EGLAPIENTRY WaitClient(void)
  864. {
  865. EVENT("()");
  866. UNIMPLEMENTED(); // FIXME
  867. SetGlobalError(Error(EGL_SUCCESS));
  868. return 0;
  869. }
  870. // EGL 1.4
  871. EGLContext EGLAPIENTRY GetCurrentContext(void)
  872. {
  873. EVENT("()");
  874. gl::Context *context = GetGlobalContext();
  875. SetGlobalError(Error(EGL_SUCCESS));
  876. return static_cast<EGLContext>(context);
  877. }
  878. // EGL 1.5
  879. EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
  880. {
  881. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list);
  882. UNIMPLEMENTED();
  883. return EGL_NO_SYNC;
  884. }
  885. EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync)
  886. {
  887. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync);
  888. UNIMPLEMENTED();
  889. return EGL_FALSE;
  890. }
  891. EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
  892. {
  893. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout);
  894. UNIMPLEMENTED();
  895. return 0;
  896. }
  897. EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
  898. {
  899. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value);
  900. UNIMPLEMENTED();
  901. return EGL_FALSE;
  902. }
  903. EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
  904. {
  905. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
  906. "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
  907. dpy, ctx, target, buffer, attrib_list);
  908. UNIMPLEMENTED();
  909. return EGL_NO_IMAGE;
  910. }
  911. EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image)
  912. {
  913. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
  914. UNIMPLEMENTED();
  915. return EGL_FALSE;
  916. }
  917. EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
  918. {
  919. EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
  920. platform, native_display, attrib_list);
  921. UNIMPLEMENTED();
  922. return EGL_NO_DISPLAY;
  923. }
  924. EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
  925. {
  926. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
  927. dpy, config, native_window, attrib_list);
  928. UNIMPLEMENTED();
  929. return EGL_NO_SURFACE;
  930. }
  931. EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
  932. {
  933. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
  934. dpy, config, native_pixmap, attrib_list);
  935. UNIMPLEMENTED();
  936. return EGL_NO_SURFACE;
  937. }
  938. EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
  939. {
  940. EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags);
  941. UNIMPLEMENTED();
  942. return EGL_FALSE;
  943. }
  944. __eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
  945. {
  946. EVENT("(const char *procname = \"%s\")", procname);
  947. struct Extension
  948. {
  949. const char *name;
  950. __eglMustCastToProperFunctionPointerType address;
  951. };
  952. static const Extension extensions[] =
  953. {
  954. { "eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)QuerySurfacePointerANGLE },
  955. { "eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)PostSubBufferNV },
  956. { "eglGetPlatformDisplayEXT", (__eglMustCastToProperFunctionPointerType)GetPlatformDisplayEXT },
  957. { "glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)gl::BlitFramebufferANGLE },
  958. { "glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)gl::RenderbufferStorageMultisampleANGLE },
  959. { "glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)gl::DeleteFencesNV },
  960. { "glGenFencesNV", (__eglMustCastToProperFunctionPointerType)gl::GenFencesNV },
  961. { "glIsFenceNV", (__eglMustCastToProperFunctionPointerType)gl::IsFenceNV },
  962. { "glTestFenceNV", (__eglMustCastToProperFunctionPointerType)gl::TestFenceNV },
  963. { "glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)gl::GetFenceivNV },
  964. { "glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)gl::FinishFenceNV },
  965. { "glSetFenceNV", (__eglMustCastToProperFunctionPointerType)gl::SetFenceNV },
  966. { "glGetTranslatedShaderSourceANGLE", (__eglMustCastToProperFunctionPointerType)gl::GetTranslatedShaderSourceANGLE },
  967. { "glTexStorage2DEXT", (__eglMustCastToProperFunctionPointerType)gl::TexStorage2DEXT },
  968. { "glGetGraphicsResetStatusEXT", (__eglMustCastToProperFunctionPointerType)gl::GetGraphicsResetStatusEXT },
  969. { "glReadnPixelsEXT", (__eglMustCastToProperFunctionPointerType)gl::ReadnPixelsEXT },
  970. { "glGetnUniformfvEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformfvEXT },
  971. { "glGetnUniformivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetnUniformivEXT },
  972. { "glGenQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::GenQueriesEXT },
  973. { "glDeleteQueriesEXT", (__eglMustCastToProperFunctionPointerType)gl::DeleteQueriesEXT },
  974. { "glIsQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::IsQueryEXT },
  975. { "glBeginQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::BeginQueryEXT },
  976. { "glEndQueryEXT", (__eglMustCastToProperFunctionPointerType)gl::EndQueryEXT },
  977. { "glGetQueryivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryivEXT },
  978. { "glGetQueryObjectuivEXT", (__eglMustCastToProperFunctionPointerType)gl::GetQueryObjectuivEXT },
  979. { "glDrawBuffersEXT", (__eglMustCastToProperFunctionPointerType)gl::DrawBuffersEXT },
  980. { "glVertexAttribDivisorANGLE", (__eglMustCastToProperFunctionPointerType)gl::VertexAttribDivisorANGLE },
  981. { "glDrawArraysInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawArraysInstancedANGLE },
  982. { "glDrawElementsInstancedANGLE", (__eglMustCastToProperFunctionPointerType)gl::DrawElementsInstancedANGLE },
  983. { "glGetProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::GetProgramBinaryOES },
  984. { "glProgramBinaryOES", (__eglMustCastToProperFunctionPointerType)gl::ProgramBinaryOES },
  985. { "glGetBufferPointervOES", (__eglMustCastToProperFunctionPointerType)gl::GetBufferPointervOES },
  986. { "glMapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::MapBufferOES },
  987. { "glUnmapBufferOES", (__eglMustCastToProperFunctionPointerType)gl::UnmapBufferOES },
  988. { "glMapBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::MapBufferRangeEXT },
  989. { "glFlushMappedBufferRangeEXT", (__eglMustCastToProperFunctionPointerType)gl::FlushMappedBufferRangeEXT },
  990. { "", NULL },
  991. };
  992. for (const Extension *extension = &extensions[0]; extension->address != nullptr; extension++)
  993. {
  994. if (strcmp(procname, extension->name) == 0)
  995. {
  996. return reinterpret_cast<__eglMustCastToProperFunctionPointerType>(extension->address);
  997. }
  998. }
  999. return NULL;
  1000. }
  1001. }