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
7 // entry_points_ext.cpp : Implements the EGL extension entry points.
8
9 #include "libGLESv2/entry_points_egl_ext.h"
10 #include "libGLESv2/global_state.h"
11
12 #include "libANGLE/Context.h"
13 #include "libANGLE/Display.h"
14 #include "libANGLE/Device.h"
15 #include "libANGLE/Surface.h"
16 #include "libANGLE/Stream.h"
17 #include "libANGLE/Thread.h"
18 #include "libANGLE/validationEGL.h"
19
20 #include "common/debug.h"
21
22 namespace egl
23 {
24
25 // EGL_ANGLE_query_surface_pointer
QuerySurfacePointerANGLE(EGLDisplay dpy,EGLSurface surface,EGLint attribute,void ** value)26 EGLBoolean EGLAPIENTRY QuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value)
27 {
28 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)",
29 dpy, surface, attribute, value);
30 Thread *thread = GetCurrentThread();
31
32 Display *display = static_cast<Display*>(dpy);
33 Surface *eglSurface = static_cast<Surface*>(surface);
34
35 Error error = ValidateSurface(display, eglSurface);
36 if (error.isError())
37 {
38 thread->setError(error);
39 return EGL_FALSE;
40 }
41
42 if (!display->getExtensions().querySurfacePointer)
43 {
44 thread->setError(NoError());
45 return EGL_FALSE;
46 }
47
48 if (surface == EGL_NO_SURFACE)
49 {
50 thread->setError(EglBadSurface());
51 return EGL_FALSE;
52 }
53
54 // validate the attribute parameter
55 switch (attribute)
56 {
57 case EGL_DEVICE_EXT:
58 break;
59 case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE:
60 if (!display->getExtensions().surfaceD3DTexture2DShareHandle)
61 {
62 thread->setError(EglBadAttribute());
63 return EGL_FALSE;
64 }
65 break;
66 case EGL_DXGI_KEYED_MUTEX_ANGLE:
67 if (!display->getExtensions().keyedMutex)
68 {
69 thread->setError(EglBadAttribute());
70 return EGL_FALSE;
71 }
72 break;
73 default:
74 thread->setError(EglBadAttribute());
75 return EGL_FALSE;
76 }
77
78 error = eglSurface->querySurfacePointerANGLE(attribute, value);
79 thread->setError(error);
80 return (error.isError() ? EGL_FALSE : EGL_TRUE);
81 }
82
83
84 // EGL_NV_post_sub_buffer
PostSubBufferNV(EGLDisplay dpy,EGLSurface surface,EGLint x,EGLint y,EGLint width,EGLint height)85 EGLBoolean EGLAPIENTRY PostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height)
86 {
87 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height);
88 Thread *thread = GetCurrentThread();
89
90 if (x < 0 || y < 0 || width < 0 || height < 0)
91 {
92 thread->setError(EglBadParameter());
93 return EGL_FALSE;
94 }
95
96 Display *display = static_cast<Display*>(dpy);
97 Surface *eglSurface = static_cast<Surface*>(surface);
98
99 Error error = ValidateSurface(display, eglSurface);
100 if (error.isError())
101 {
102 thread->setError(error);
103 return EGL_FALSE;
104 }
105
106 if (display->testDeviceLost())
107 {
108 thread->setError(EglContextLost());
109 return EGL_FALSE;
110 }
111
112 if (surface == EGL_NO_SURFACE)
113 {
114 thread->setError(EglBadSurface());
115 return EGL_FALSE;
116 }
117
118 if (!display->getExtensions().postSubBuffer)
119 {
120 // Spec is not clear about how this should be handled.
121 thread->setError(NoError());
122 return EGL_TRUE;
123 }
124
125 // TODO(jmadill): Validate Surface is bound to the thread.
126 error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
127 if (error.isError())
128 {
129 thread->setError(error);
130 return EGL_FALSE;
131 }
132
133 thread->setError(NoError());
134 return EGL_TRUE;
135 }
136
137 // EGL_EXT_platform_base
GetPlatformDisplayEXT(EGLenum platform,void * native_display,const EGLint * attrib_list)138 EGLDisplay EGLAPIENTRY GetPlatformDisplayEXT(EGLenum platform, void *native_display, const EGLint *attrib_list)
139 {
140 EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
141 platform, native_display, attrib_list);
142 Thread *thread = GetCurrentThread();
143
144 Error err = ValidateGetPlatformDisplayEXT(platform, native_display, attrib_list);
145 thread->setError(err);
146 if (err.isError())
147 {
148 return EGL_NO_DISPLAY;
149 }
150
151 const auto &attribMap = AttributeMap::CreateFromIntArray(attrib_list);
152 if (platform == EGL_PLATFORM_ANGLE_ANGLE)
153 {
154 return Display::GetDisplayFromNativeDisplay(
155 gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
156 }
157 else if (platform == EGL_PLATFORM_DEVICE_EXT)
158 {
159 Device *eglDevice = reinterpret_cast<Device *>(native_display);
160 return Display::GetDisplayFromDevice(eglDevice, attribMap);
161 }
162 else
163 {
164 UNREACHABLE();
165 return EGL_NO_DISPLAY;
166 }
167 }
168
169 // EGL_EXT_device_query
QueryDeviceAttribEXT(EGLDeviceEXT device,EGLint attribute,EGLAttrib * value)170 EGLBoolean EGLAPIENTRY QueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value)
171 {
172 EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
173 device, attribute, value);
174 Thread *thread = GetCurrentThread();
175
176 Device *dev = static_cast<Device*>(device);
177 if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev))
178 {
179 thread->setError(EglBadAccess());
180 return EGL_FALSE;
181 }
182
183 // If the device was created by (and is owned by) a display, and that display doesn't support
184 // device querying, then this call should fail
185 Display *owningDisplay = dev->getOwningDisplay();
186 if (owningDisplay != nullptr && !owningDisplay->getExtensions().deviceQuery)
187 {
188 thread->setError(EglBadAccess() << "Device wasn't created using eglCreateDeviceANGLE, "
189 "and the Display that created it doesn't support "
190 "device querying");
191 return EGL_FALSE;
192 }
193
194 Error error(NoError());
195
196 // validate the attribute parameter
197 switch (attribute)
198 {
199 case EGL_D3D11_DEVICE_ANGLE:
200 case EGL_D3D9_DEVICE_ANGLE:
201 if (!dev->getExtensions().deviceD3D || dev->getType() != attribute)
202 {
203 thread->setError(EglBadAttribute());
204 return EGL_FALSE;
205 }
206 error = dev->getDevice(value);
207 break;
208 default:
209 thread->setError(EglBadAttribute());
210 return EGL_FALSE;
211 }
212
213 thread->setError(error);
214 return (error.isError() ? EGL_FALSE : EGL_TRUE);
215 }
216
217 // EGL_EXT_device_query
QueryDeviceStringEXT(EGLDeviceEXT device,EGLint name)218 const char * EGLAPIENTRY QueryDeviceStringEXT(EGLDeviceEXT device, EGLint name)
219 {
220 EVENT("(EGLDeviceEXT device = 0x%0.8p, EGLint name = %d)",
221 device, name);
222 Thread *thread = GetCurrentThread();
223
224 Device *dev = static_cast<Device*>(device);
225 if (dev == EGL_NO_DEVICE_EXT || !Device::IsValidDevice(dev))
226 {
227 thread->setError(EglBadDevice());
228 return nullptr;
229 }
230
231 const char *result;
232 switch (name)
233 {
234 case EGL_EXTENSIONS:
235 result = dev->getExtensionString().c_str();
236 break;
237 default:
238 thread->setError(EglBadDevice());
239 return nullptr;
240 }
241
242 thread->setError(NoError());
243 return result;
244 }
245
246 // EGL_EXT_device_query
QueryDisplayAttribEXT(EGLDisplay dpy,EGLint attribute,EGLAttrib * value)247 EGLBoolean EGLAPIENTRY QueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute, EGLAttrib *value)
248 {
249 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint attribute = %d, EGLAttrib *value = 0x%0.8p)",
250 dpy, attribute, value);
251 Thread *thread = GetCurrentThread();
252
253 Display *display = static_cast<Display*>(dpy);
254
255 Error error = ValidateDisplay(display);
256 if (error.isError())
257 {
258 thread->setError(error);
259 return EGL_FALSE;
260 }
261
262 if (!display->getExtensions().deviceQuery)
263 {
264 thread->setError(EglBadAccess());
265 return EGL_FALSE;
266 }
267
268 // validate the attribute parameter
269 switch (attribute)
270 {
271 case EGL_DEVICE_EXT:
272 *value = reinterpret_cast<EGLAttrib>(display->getDevice());
273 break;
274
275 default:
276 thread->setError(EglBadAttribute());
277 return EGL_FALSE;
278 }
279
280 thread->setError(error);
281 return (error.isError() ? EGL_FALSE : EGL_TRUE);
282 }
283
CreateImageKHR(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)284 ANGLE_EXPORT EGLImageKHR EGLAPIENTRY CreateImageKHR(EGLDisplay dpy,
285 EGLContext ctx,
286 EGLenum target,
287 EGLClientBuffer buffer,
288 const EGLint *attrib_list)
289 {
290 EVENT(
291 "(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
292 "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
293 dpy, ctx, target, buffer, attrib_list);
294 Thread *thread = GetCurrentThread();
295
296 Display *display = static_cast<Display *>(dpy);
297 gl::Context *context = static_cast<gl::Context *>(ctx);
298 AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
299
300 Error error = ValidateCreateImageKHR(display, context, target, buffer, attributes);
301 if (error.isError())
302 {
303 thread->setError(error);
304 return EGL_NO_IMAGE;
305 }
306
307 Image *image = nullptr;
308 error = display->createImage(context, target, buffer, attributes, &image);
309 if (error.isError())
310 {
311 thread->setError(error);
312 return EGL_NO_IMAGE;
313 }
314
315 return static_cast<EGLImage>(image);
316 }
317
DestroyImageKHR(EGLDisplay dpy,EGLImageKHR image)318 ANGLE_EXPORT EGLBoolean EGLAPIENTRY DestroyImageKHR(EGLDisplay dpy, EGLImageKHR image)
319 {
320 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
321 Thread *thread = GetCurrentThread();
322
323 Display *display = static_cast<Display *>(dpy);
324 Image *img = static_cast<Image *>(image);
325
326 Error error = ValidateDestroyImageKHR(display, img);
327 if (error.isError())
328 {
329 thread->setError(error);
330 return EGL_FALSE;
331 }
332
333 display->destroyImage(img);
334
335 return EGL_TRUE;
336 }
337
CreateDeviceANGLE(EGLint device_type,void * native_device,const EGLAttrib * attrib_list)338 ANGLE_EXPORT EGLDeviceEXT EGLAPIENTRY CreateDeviceANGLE(EGLint device_type,
339 void *native_device,
340 const EGLAttrib *attrib_list)
341 {
342 EVENT(
343 "(EGLint device_type = %d, void* native_device = 0x%0.8p, const EGLAttrib* attrib_list = "
344 "0x%0.8p)",
345 device_type, native_device, attrib_list);
346 Thread *thread = GetCurrentThread();
347
348 Error error = ValidateCreateDeviceANGLE(device_type, native_device, attrib_list);
349 if (error.isError())
350 {
351 thread->setError(error);
352 return EGL_NO_DEVICE_EXT;
353 }
354
355 Device *device = nullptr;
356 error = Device::CreateDevice(native_device, device_type, &device);
357 if (error.isError())
358 {
359 ASSERT(device == nullptr);
360 thread->setError(error);
361 return EGL_NO_DEVICE_EXT;
362 }
363
364 return device;
365 }
366
ReleaseDeviceANGLE(EGLDeviceEXT device)367 ANGLE_EXPORT EGLBoolean EGLAPIENTRY ReleaseDeviceANGLE(EGLDeviceEXT device)
368 {
369 EVENT("(EGLDeviceEXT device = 0x%0.8p)", device);
370 Thread *thread = GetCurrentThread();
371
372 Device *dev = static_cast<Device *>(device);
373
374 Error error = ValidateReleaseDeviceANGLE(dev);
375 if (error.isError())
376 {
377 thread->setError(error);
378 return EGL_FALSE;
379 }
380
381 SafeDelete(dev);
382
383 return EGL_TRUE;
384 }
385
386 // EGL_KHR_stream
CreateStreamKHR(EGLDisplay dpy,const EGLint * attrib_list)387 EGLStreamKHR EGLAPIENTRY CreateStreamKHR(EGLDisplay dpy, const EGLint *attrib_list)
388 {
389 EVENT("(EGLDisplay dpy = 0x%0.8p, const EGLAttrib* attrib_list = 0x%0.8p)", dpy, attrib_list);
390 Thread *thread = GetCurrentThread();
391
392 Display *display = static_cast<Display *>(dpy);
393 AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
394
395 Error error = ValidateCreateStreamKHR(display, attributes);
396 if (error.isError())
397 {
398 thread->setError(error);
399 return EGL_NO_STREAM_KHR;
400 }
401
402 Stream *stream;
403 error = display->createStream(attributes, &stream);
404 if (error.isError())
405 {
406 thread->setError(error);
407 return EGL_NO_STREAM_KHR;
408 }
409
410 thread->setError(error);
411 return static_cast<EGLStreamKHR>(stream);
412 }
413
DestroyStreamKHR(EGLDisplay dpy,EGLStreamKHR stream)414 EGLBoolean EGLAPIENTRY DestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream)
415 {
416 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
417 Thread *thread = GetCurrentThread();
418
419 Display *display = static_cast<Display *>(dpy);
420 Stream *streamObject = static_cast<Stream *>(stream);
421
422 Error error = ValidateDestroyStreamKHR(display, streamObject);
423 if (error.isError())
424 {
425 thread->setError(error);
426 return EGL_FALSE;
427 }
428
429 display->destroyStream(streamObject);
430 thread->setError(error);
431 return EGL_TRUE;
432 }
433
StreamAttribKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint value)434 EGLBoolean EGLAPIENTRY StreamAttribKHR(EGLDisplay dpy,
435 EGLStreamKHR stream,
436 EGLenum attribute,
437 EGLint value)
438 {
439 EVENT(
440 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
441 "EGLint value = 0x%X)",
442 dpy, stream, attribute, value);
443 Thread *thread = GetCurrentThread();
444
445 Display *display = static_cast<Display *>(dpy);
446 Stream *streamObject = static_cast<Stream *>(stream);
447
448 Error error = ValidateStreamAttribKHR(display, streamObject, attribute, value);
449 if (error.isError())
450 {
451 thread->setError(error);
452 return EGL_FALSE;
453 }
454
455 switch (attribute)
456 {
457 case EGL_CONSUMER_LATENCY_USEC_KHR:
458 streamObject->setConsumerLatency(value);
459 break;
460 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
461 streamObject->setConsumerAcquireTimeout(value);
462 break;
463 default:
464 UNREACHABLE();
465 }
466
467 thread->setError(error);
468 return EGL_TRUE;
469 }
470
QueryStreamKHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLint * value)471 EGLBoolean EGLAPIENTRY QueryStreamKHR(EGLDisplay dpy,
472 EGLStreamKHR stream,
473 EGLenum attribute,
474 EGLint *value)
475 {
476 EVENT(
477 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
478 "EGLint value = 0x%0.8p)",
479 dpy, stream, attribute, value);
480 Thread *thread = GetCurrentThread();
481
482 Display *display = static_cast<Display *>(dpy);
483 Stream *streamObject = static_cast<Stream *>(stream);
484
485 Error error = ValidateQueryStreamKHR(display, streamObject, attribute, value);
486 if (error.isError())
487 {
488 thread->setError(error);
489 return EGL_FALSE;
490 }
491
492 switch (attribute)
493 {
494 case EGL_STREAM_STATE_KHR:
495 *value = streamObject->getState();
496 break;
497 case EGL_CONSUMER_LATENCY_USEC_KHR:
498 *value = streamObject->getConsumerLatency();
499 break;
500 case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
501 *value = streamObject->getConsumerAcquireTimeout();
502 break;
503 default:
504 UNREACHABLE();
505 }
506
507 thread->setError(error);
508 return EGL_TRUE;
509 }
510
QueryStreamu64KHR(EGLDisplay dpy,EGLStreamKHR stream,EGLenum attribute,EGLuint64KHR * value)511 EGLBoolean EGLAPIENTRY QueryStreamu64KHR(EGLDisplay dpy,
512 EGLStreamKHR stream,
513 EGLenum attribute,
514 EGLuint64KHR *value)
515 {
516 EVENT(
517 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLenum attribute = 0x%X, "
518 "EGLuint64KHR value = 0x%0.8p)",
519 dpy, stream, attribute, value);
520 Thread *thread = GetCurrentThread();
521
522 Display *display = static_cast<Display *>(dpy);
523 Stream *streamObject = static_cast<Stream *>(stream);
524
525 Error error = ValidateQueryStreamu64KHR(display, streamObject, attribute, value);
526 if (error.isError())
527 {
528 thread->setError(error);
529 return EGL_FALSE;
530 }
531
532 switch (attribute)
533 {
534 case EGL_PRODUCER_FRAME_KHR:
535 *value = streamObject->getProducerFrame();
536 break;
537 case EGL_CONSUMER_FRAME_KHR:
538 *value = streamObject->getConsumerFrame();
539 break;
540 default:
541 UNREACHABLE();
542 }
543
544 thread->setError(error);
545 return EGL_TRUE;
546 }
547
StreamConsumerGLTextureExternalKHR(EGLDisplay dpy,EGLStreamKHR stream)548 EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalKHR(EGLDisplay dpy, EGLStreamKHR stream)
549 {
550 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
551 Thread *thread = GetCurrentThread();
552
553 Display *display = static_cast<Display *>(dpy);
554 Stream *streamObject = static_cast<Stream *>(stream);
555 gl::Context *context = gl::GetValidGlobalContext();
556
557 Error error = ValidateStreamConsumerGLTextureExternalKHR(display, context, streamObject);
558 if (error.isError())
559 {
560 thread->setError(error);
561 return EGL_FALSE;
562 }
563
564 error = streamObject->createConsumerGLTextureExternal(AttributeMap(), context);
565 if (error.isError())
566 {
567 thread->setError(error);
568 return EGL_FALSE;
569 }
570
571 thread->setError(error);
572 return EGL_TRUE;
573 }
574
StreamConsumerAcquireKHR(EGLDisplay dpy,EGLStreamKHR stream)575 EGLBoolean EGLAPIENTRY StreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream)
576 {
577 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
578 Thread *thread = GetCurrentThread();
579
580 Display *display = static_cast<Display *>(dpy);
581 Stream *streamObject = static_cast<Stream *>(stream);
582 gl::Context *context = gl::GetValidGlobalContext();
583
584 Error error = ValidateStreamConsumerAcquireKHR(display, context, streamObject);
585 if (error.isError())
586 {
587 thread->setError(error);
588 return EGL_FALSE;
589 }
590
591 error = streamObject->consumerAcquire(context);
592 if (error.isError())
593 {
594 thread->setError(error);
595 return EGL_FALSE;
596 }
597
598 thread->setError(error);
599 return EGL_TRUE;
600 }
601
StreamConsumerReleaseKHR(EGLDisplay dpy,EGLStreamKHR stream)602 EGLBoolean EGLAPIENTRY StreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream)
603 {
604 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR = 0x%0.8p)", dpy, stream);
605 Thread *thread = GetCurrentThread();
606
607 Display *display = static_cast<Display *>(dpy);
608 Stream *streamObject = static_cast<Stream *>(stream);
609 gl::Context *context = gl::GetValidGlobalContext();
610
611 Error error = ValidateStreamConsumerReleaseKHR(display, context, streamObject);
612 if (error.isError())
613 {
614 thread->setError(error);
615 return EGL_FALSE;
616 }
617
618 error = streamObject->consumerRelease(context);
619 if (error.isError())
620 {
621 thread->setError(error);
622 return EGL_FALSE;
623 }
624
625 thread->setError(error);
626 return EGL_TRUE;
627 }
628
StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,EGLStreamKHR stream,const EGLAttrib * attrib_list)629 EGLBoolean EGLAPIENTRY StreamConsumerGLTextureExternalAttribsNV(EGLDisplay dpy,
630 EGLStreamKHR stream,
631 const EGLAttrib *attrib_list)
632 {
633 EVENT(
634 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
635 dpy, stream, attrib_list);
636 Thread *thread = GetCurrentThread();
637
638 Display *display = static_cast<Display *>(dpy);
639 Stream *streamObject = static_cast<Stream *>(stream);
640 gl::Context *context = gl::GetValidGlobalContext();
641 AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
642
643 Error error = ValidateStreamConsumerGLTextureExternalAttribsNV(display, context, streamObject,
644 attributes);
645 if (error.isError())
646 {
647 thread->setError(error);
648 return EGL_FALSE;
649 }
650
651 error = streamObject->createConsumerGLTextureExternal(attributes, context);
652 if (error.isError())
653 {
654 thread->setError(error);
655 return EGL_FALSE;
656 }
657
658 thread->setError(error);
659 return EGL_TRUE;
660 }
661
CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,EGLStreamKHR stream,const EGLAttrib * attrib_list)662 EGLBoolean EGLAPIENTRY CreateStreamProducerD3DTextureNV12ANGLE(EGLDisplay dpy,
663 EGLStreamKHR stream,
664 const EGLAttrib *attrib_list)
665 {
666 EVENT(
667 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, EGLAttrib attrib_list = 0x%0.8p",
668 dpy, stream, attrib_list);
669 Thread *thread = GetCurrentThread();
670
671 Display *display = static_cast<Display *>(dpy);
672 Stream *streamObject = static_cast<Stream *>(stream);
673 AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
674
675 Error error =
676 ValidateCreateStreamProducerD3DTextureNV12ANGLE(display, streamObject, attributes);
677 if (error.isError())
678 {
679 thread->setError(error);
680 return EGL_FALSE;
681 }
682
683 error = streamObject->createProducerD3D11TextureNV12(attributes);
684 if (error.isError())
685 {
686 thread->setError(error);
687 return EGL_FALSE;
688 }
689
690 thread->setError(error);
691 return EGL_TRUE;
692 }
693
StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,EGLStreamKHR stream,void * texture,const EGLAttrib * attrib_list)694 EGLBoolean EGLAPIENTRY StreamPostD3DTextureNV12ANGLE(EGLDisplay dpy,
695 EGLStreamKHR stream,
696 void *texture,
697 const EGLAttrib *attrib_list)
698 {
699 EVENT(
700 "(EGLDisplay dpy = 0x%0.8p, EGLStreamKHR stream = 0x%0.8p, void* texture = 0x%0.8p, "
701 "EGLAttrib attrib_list = 0x%0.8p",
702 dpy, stream, texture, attrib_list);
703 Thread *thread = GetCurrentThread();
704
705 Display *display = static_cast<Display *>(dpy);
706 Stream *streamObject = static_cast<Stream *>(stream);
707 AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
708
709 Error error = ValidateStreamPostD3DTextureNV12ANGLE(display, streamObject, texture, attributes);
710 if (error.isError())
711 {
712 thread->setError(error);
713 return EGL_FALSE;
714 }
715
716 error = streamObject->postD3D11NV12Texture(texture, attributes);
717 if (error.isError())
718 {
719 thread->setError(error);
720 return EGL_FALSE;
721 }
722
723 thread->setError(error);
724 return EGL_TRUE;
725 }
726
GetSyncValuesCHROMIUM(EGLDisplay dpy,EGLSurface surface,EGLuint64KHR * ust,EGLuint64KHR * msc,EGLuint64KHR * sbc)727 EGLBoolean EGLAPIENTRY GetSyncValuesCHROMIUM(EGLDisplay dpy,
728 EGLSurface surface,
729 EGLuint64KHR *ust,
730 EGLuint64KHR *msc,
731 EGLuint64KHR *sbc)
732 {
733 EVENT(
734 "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLuint64KHR* ust = 0x%0.8p, "
735 "EGLuint64KHR* msc = 0x%0.8p, EGLuint64KHR* sbc = 0x%0.8p",
736 dpy, surface, ust, msc, sbc);
737 Thread *thread = GetCurrentThread();
738
739 Display *display = static_cast<Display *>(dpy);
740 Surface *eglSurface = static_cast<Surface *>(surface);
741
742 Error error = ValidateGetSyncValuesCHROMIUM(display, eglSurface, ust, msc, sbc);
743 if (error.isError())
744 {
745 thread->setError(error);
746 return EGL_FALSE;
747 }
748
749 error = eglSurface->getSyncValues(ust, msc, sbc);
750 if (error.isError())
751 {
752 thread->setError(error);
753 return EGL_FALSE;
754 }
755
756 thread->setError(error);
757 return EGL_TRUE;
758 }
759
SwapBuffersWithDamageEXT(EGLDisplay dpy,EGLSurface surface,EGLint * rects,EGLint n_rects)760 ANGLE_EXPORT EGLBoolean SwapBuffersWithDamageEXT(EGLDisplay dpy,
761 EGLSurface surface,
762 EGLint *rects,
763 EGLint n_rects)
764 {
765 EVENT(
766 "(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint *rects = 0x%0.8p, EGLint "
767 "n_rects = %d)",
768 dpy, surface, rects, n_rects);
769 Thread *thread = GetCurrentThread();
770
771 Display *display = static_cast<Display *>(dpy);
772 Surface *eglSurface = static_cast<Surface *>(surface);
773
774 Error error = ValidateSwapBuffersWithDamageEXT(display, eglSurface, rects, n_rects);
775 if (error.isError())
776 {
777 thread->setError(error);
778 return EGL_FALSE;
779 }
780
781 error = eglSurface->swapWithDamage(thread->getContext(), rects, n_rects);
782 if (error.isError())
783 {
784 thread->setError(error);
785 return EGL_FALSE;
786 }
787
788 return EGL_TRUE;
789 }
790
ProgramCacheGetAttribANGLE(EGLDisplay dpy,EGLenum attrib)791 EGLint EGLAPIENTRY ProgramCacheGetAttribANGLE(EGLDisplay dpy, EGLenum attrib)
792 {
793 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum attrib = 0x%X)", dpy, attrib);
794
795 Display *display = static_cast<Display *>(dpy);
796 Thread *thread = GetCurrentThread();
797
798 ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheGetAttribANGLE(display, attrib), 0);
799
800 return display->programCacheGetAttrib(attrib);
801 }
802
ProgramCacheQueryANGLE(EGLDisplay dpy,EGLint index,void * key,EGLint * keysize,void * binary,EGLint * binarysize)803 void EGLAPIENTRY ProgramCacheQueryANGLE(EGLDisplay dpy,
804 EGLint index,
805 void *key,
806 EGLint *keysize,
807 void *binary,
808 EGLint *binarysize)
809 {
810 EVENT(
811 "(EGLDisplay dpy = 0x%0.8p, EGLint index = %d, void *key = 0x%0.8p, EGLint *keysize = "
812 "0x%0.8p, void *binary = 0x%0.8p, EGLint *size = 0x%0.8p)",
813 dpy, index, key, keysize, binary, binarysize);
814
815 Display *display = static_cast<Display *>(dpy);
816 Thread *thread = GetCurrentThread();
817
818 ANGLE_EGL_TRY(thread,
819 ValidateProgramCacheQueryANGLE(display, index, key, keysize, binary, binarysize));
820
821 ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize));
822 }
823
ProgramCachePopulateANGLE(EGLDisplay dpy,const void * key,EGLint keysize,const void * binary,EGLint binarysize)824 void EGLAPIENTRY ProgramCachePopulateANGLE(EGLDisplay dpy,
825 const void *key,
826 EGLint keysize,
827 const void *binary,
828 EGLint binarysize)
829 {
830 EVENT(
831 "(EGLDisplay dpy = 0x%0.8p, void *key = 0x%0.8p, EGLint keysize = %d, void *binary = "
832 "0x%0.8p, EGLint *size = 0x%0.8p)",
833 dpy, key, keysize, binary, binarysize);
834
835 Display *display = static_cast<Display *>(dpy);
836 Thread *thread = GetCurrentThread();
837
838 ANGLE_EGL_TRY(thread,
839 ValidateProgramCachePopulateANGLE(display, key, keysize, binary, binarysize));
840
841 ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize));
842 }
843
ProgramCacheResizeANGLE(EGLDisplay dpy,EGLint limit,EGLenum mode)844 EGLint EGLAPIENTRY ProgramCacheResizeANGLE(EGLDisplay dpy, EGLint limit, EGLenum mode)
845 {
846 EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint limit = %d, EGLenum mode = 0x%X)", dpy, limit, mode);
847
848 Display *display = static_cast<Display *>(dpy);
849 Thread *thread = GetCurrentThread();
850
851 ANGLE_EGL_TRY_RETURN(thread, ValidateProgramCacheResizeANGLE(display, limit, mode), 0);
852
853 return display->programCacheResize(limit, mode);
854 }
855
856 } // namespace egl
857