QortalOS Brooklyn for Raspberry Pi 4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

579 lines
22 KiB

/*
Copyright (c) 2012, Broadcom Europe Ltd
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
Khronos documentation:
3.1 Errors
Where possible, when an EGL function fails it has no side effects.
EGL functions usually return an indicator of success or failure; either an
EGLBoolean EGL TRUE or EGL FALSE value, or in the form of an out-of-band
return value indicating failure, such as returning EGL NO CONTEXT instead of a requested
context handle. Additional information about the success or failure of the
most recent EGL function called in a specific thread, in the form of an error code,
can be obtained by calling
EGLint eglGetError();
The error codes that may be returned from eglGetError, and their meanings,
are:
EGL SUCCESS
Function succeeded.
EGL NOT INITIALIZED
EGL is not initialized, or could not be initialized, for the specified display.
EGL BAD ACCESS
EGL cannot access a requested resource (for example, a context is bound in
another thread).
EGL BAD ALLOC
EGL failed to allocate resources for the requested operation.
9
10 CHAPTER 3. EGL FUNCTIONS AND ERRORS
EGL BAD ATTRIBUTE
An unrecognized attribute or attribute value was passed in an attribute list.
EGL BAD CONTEXT
An EGLContext argument does not name a valid EGLContext.
EGL BAD CONFIG
An EGLConfig argument does not name a valid EGLConfig.
EGL BAD CURRENT SURFACE
The current surface of the calling thread is a window, pbuffer, or pixmap that
is no longer valid.
EGL BAD DISPLAY
An EGLDisplay argument does not name a valid EGLDisplay; or, EGL
is not initialized on the specified EGLDisplay.
EGL BAD SURFACE
An EGLSurface argument does not name a valid surface (window, pbuffer,
or pixmap) configured for rendering.
EGL BAD MATCH
Arguments are inconsistent; for example, an otherwise valid context requires
buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.
EGL BAD PARAMETER
One or more argument values are invalid.
EGL BAD NATIVE PIXMAP
An EGLNativePixmapType argument does not refer to a valid native
pixmap.
EGL BAD NATIVE WINDOW
An EGLNativeWindowType argument does not refer to a valid native
window.
EGL CONTEXT LOST
A power management event has occurred. The application must destroy all
contexts and reinitialise client API state and objects to continue rendering,
as described in section 2.6.
When there is no status to return (in other words, when eglGetError is called
as the first EGL call in a thread, or immediately after calling eglReleaseThread),
EGL SUCCESS will be returned.
Implementation notes:
What should we do if eglGetError is called twice? Currently we reset the error to EGL_SUCCESS.
Preconditions:
-
Postconditions:
Result is in the list (CLIENT_THREAD_STATE_ERROR)
Invariants preserved:
-
Invariants used:
(CLIENT_THREAD_STATE_ERROR)
*/
EGLAPI EGLint EGLAPIENTRY eglGetError(void)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
if (thread)
{
EGLint result;
vcos_assert( thread != NULL );
result = thread->error;
thread->error = EGL_SUCCESS;
return result;
}
else
return EGL_SUCCESS;
}
/*
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
Khronos documentation:
3.2 Initialization
Initialization must be performed once for each display prior to calling most other
EGL or client API functions. A display can be obtained by calling
EGLDisplay eglGetDisplay(EGLNativeDisplayType
display id);
The type and format of display id are implementation-specific, and it describes a
specific display provided by the system EGL is running on. For example, an EGL
implementation under X windows would require display id to be an X Display,
while an implementation under Microsoft Windows would require display id to be
a Windows Device Context. If display id is EGL DEFAULT DISPLAY, a default
display is returned.
If no display matching display id is available, EGL NO DISPLAY is returned;
no error condition is raised in this case.
Implementation notes:
We only support one display. This is assumed to have a native display_id
of 0 (==EGL_DEFAULT_DISPLAY) and an EGLDisplay id of 1
Preconditions:
-
Postconditions:
-
Invariants preserved:
-
Invariants used:
-
*/
EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
{
CLIENT_THREAD_STATE_T *thread = CLIENT_GET_CHECK_THREAD_STATE();
if (thread)
thread->error = EGL_SUCCESS;
return khrn_platform_set_display_id(display_id);
}
//eglInitialize
//eglTerminate
//eglQueryString
/*
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
Khronos documentation:
3.4.1 Querying Configurations
Use
EGLBoolean eglGetConfigs(EGLDisplay dpy,
EGLConfig *configs, EGLint config size,
EGLint *num config);
to get the list of all EGLConfigs that are available on the specified display. configs
is a pointer to a buffer containing config size elements. On success, EGL TRUE is
returned. The number of configurations is returned in num config, and elements 0
through num config - 1 of configs are filled in with the valid EGLConfigs. No
more than config size EGLConfigs will be returned even if more are available on
the specified display. However, if eglGetConfigs is called with configs = NULL,
then no configurations are returned, but the total number of configurations available
will be returned in num config.
On failure, EGL FALSE is returned. An EGL NOT INITIALIZED error is generated
if EGL is not initialized on dpy. An EGL BAD PARAMETER error is generated
if num config is NULL.
Implementation notes:
-
Preconditions:
configs is NULL or a valid pointer to config_size elements
num_config is NULL or a valid pointer
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
EGL_BAD_PARAMETER num_config is null
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
Invariants preserved:
-
Invariants used:
-
*/
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!num_config) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else if (!configs) {
thread->error = EGL_SUCCESS;
*num_config = EGL_MAX_CONFIGS;
result = EGL_TRUE;
} else {
int i;
for (i = 0; i < EGL_MAX_CONFIGS && i < config_size; i++)
configs[i] = egl_config_from_id(i);
thread->error = EGL_SUCCESS;
*num_config = i;
result = EGL_TRUE;
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}
/*
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
Khronos documentation:
Use
EGLBoolean eglChooseConfig(EGLDisplay dpy, const
EGLint *attrib list, EGLConfig *configs,
EGLint config size, EGLint *num config);
to get EGLConfigs that match a list of attributes. The return value and the meaning
of configs, config size, and num config are the same as for eglGetConfigs.
However, only configurations matching attrib list, as discussed below, will be returned.
On failure, EGL FALSE is returned. An EGL BAD ATTRIBUTE error is generated
if attrib list contains an undefined EGL attribute or an attribute value that is
unrecognized or out of range.
All attribute names in attrib list are immediately followed by the corresponding
desired value. The list is terminated with EGL NONE. If an attribute is not specified
in attrib list, then the default value (listed in Table 3.4) is used (it is said to be
specified implicitly). If EGL_DONT_CARE is specified as an attribute value, then the
attribute will not be checked. EGL_DONT_CARE may be specified for all attributes
except EGL LEVEL. If attrib list is NULL or empty (first attribute is EGL NONE),
then selection and sorting of EGLConfigs is done according to the default criteria
in Tables 3.4 and 3.1, as described below under Selection and Sorting.
Selection of EGLConfigs
Attributes are matched in an attribute-specific manner, as shown in the <EFBFBD>Selection
Critera<EFBFBD> column of table 3.4. The criteria listed in the table have the following
meanings:
AtLeast Only EGLConfigs with an attribute value that meets or exceeds the
specified value are selected.
Exact Only EGLConfigs whose attribute value equals the specified value are
matched.
Mask Only EGLConfigs for which the bits set in the attribute value include all
the bits that are set in the specified value are selected (additional bits might
be set in the attribute value).
Special As described for the specific attribute.
Some of the attributes must match the specified value exactly; others, such as
EGL RED SIZE, must meet or exceed the specified minimum values.
To retrieve an EGLConfig given its unique integer ID, use the
EGL CONFIG ID attribute. When EGL CONFIG ID is specified, all other attributes
are ignored, and only the EGLConfig with the given ID is returned.
If EGL MAX PBUFFER WIDTH, EGL MAX PBUFFER HEIGHT,
EGL MAX PBUFFER PIXELS, or EGL NATIVE VISUAL ID are specified in
attrib list, then they are ignored (however, if present, these attributes must still be
Version 1.3 - December 4, 2006
3.4. CONFIGURATION MANAGEMENT 21
followed by an attribute value in attrib list). If EGL SURFACE TYPE is specified
in attrib list and the mask that follows does not have EGL WINDOW BIT set, or if
there are no native visual types, then the EGL NATIVE VISUAL TYPE attribute is
ignored.
If EGL TRANSPARENT TYPE is set to EGL NONE in attrib list, then
the EGL TRANSPARENT RED VALUE, EGL TRANSPARENT GREEN VALUE, and
EGL TRANSPARENT BLUE VALUE attributes are ignored.
If EGL MATCH NATIVE PIXMAP is specified in attrib list, it must be followed
by an attribute value which is the handle of a valid native pixmap. Only
EGLConfigs which support rendering to that pixmap will match this attribute2.
If no EGLConfig matching the attribute list exists, then the call succeeds, but
num config is set to 0.
Attribute Default Selection Sort Sort
Criteria Order Priority
EGL_BUFFER_SIZE 0 AtLeast Smaller 4
EGL_RED_SIZE 0 AtLeast Special 3
EGL_GREEN_SIZE 0 AtLeast Special 3
EGL_BLUE_SIZE 0 AtLeast Special 3
EGL_LUMINANCE_SIZE 0 AtLeast Special 3
EGL_ALPHA_SIZE 0 AtLeast Special 3
EGL_ALPHA_MASK_SIZE 0 AtLeast Smaller 9
EGL_BIND_TO_TEXTURE_RGB EGL_DONT_CARE Exact None
EGL_BIND_TO_TEXTURE_RGBA EGL_DONT_CARE Exact None
EGL_COLOR_BUFFER_TYPE EGL_RGB BUFFER Exact None 2
EGL_CONFIG_CAVEAT EGL_DONT_CARE Exact Special 1
EGL_CONFIG_ID EGL_DONT_CARE Exact Smaller 11 (last)
EGL_CONFORMANT 0 Mask None
EGL_DEPTH_SIZE 0 AtLeast Smaller 7
EGL_LEVEL 0 Exact None
EGL_MATCH_NATIVE_PIXMAP EGL_NONE Special None
EGL_MAX_SWAP_INTERVAL EGL_DONT_CARE Exact None
EGL_MIN_SWAP_INTERVAL EGL_DONT_CARE Exact None
EGL_NATIVE_RENDERABLE EGL_DONT_CARE Exact None
EGL_NATIVE_VISUAL_TYPE EGL_DONT_CARE Exact Special 10
EGL_RENDERABLE_TYPE EGL_OPENGL_ES_BIT Mask None
EGL_SAMPLE_BUFFERS 0 AtLeast Smaller 5
EGL_SAMPLES 0 AtLeast Smaller 6
EGL_STENCIL_SIZE 0 AtLeast Smaller 8
EGL_SURFACE_TYPE EGL_WINDOW_BIT Mask None
EGL_TRANSPARENT_TYPE EGL_NONE Exact None
EGL_TRANSPARENT_RED_VALUE EGL_DONT_CARE Exact None
EGL_TRANSPARENT_GREEN_VALUE EGL_DONT_CARE Exact None
EGL_TRANSPARENT_BLUE_VALUE EGL_DONT_CARE Exact None
Table 3.4: Default values and match criteria for EGLConfig attributes.
2 The special match criteria for EGL MATCH NATIVE PIXMAP was introduced due to the
difficulty of determining an EGLConfig equivalent to a native pixmap using only color component
depths.
3This rule places configs with deeper color buffers first in the list returned by eglChooseConfig.
Applications may find this counterintuitive, and need to perform additional processing on the list of
configs to find one best matching their requirements. For example, specifying RGBA depths of 5651
could return a list whose first config has a depth of 8888.
Implementation notes:
Configurations are not always returned in the same order; the sort order depends on
whether we care about EGL_RED_SIZE, EGL_GREEN_SIZE, etc. So we need to extract the information
about which of these we care about, then pass this to a sorting function.
Preconditions:
configs is NULL or a valid pointer to config_size elements
num_config is NULL or a valid pointer
attrib_list is NULL or a pointer to an EGL_NONE-terminated list of attribute/value pairs
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for dpy
EGL_BAD_PARAMETER num_config is null
EGL_BAD_ATTRIBUTE attrib_list contains an undefined EGL attribute
EGL_BAD_ATTRIBUTE attrib_list contains an attribute value that is unrecognized or out of range.
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
Invariants preserved:
-
Invariants used:
-
*/
static EGLBoolean choose_config(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config, bool sane)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!num_config) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else {
/*
check for invalid attributes, and find color components for which
we have expressed a preference
*/
bool use_red = false;
bool use_green = false;
bool use_blue = false;
bool use_alpha = false;
if (!egl_config_check_attribs(attrib_list, &use_red, &use_green, &use_blue, &use_alpha)) {
thread->error = EGL_BAD_ATTRIBUTE;
result = EGL_FALSE;
} else {
/*
sort configs
*/
int ids[EGL_MAX_CONFIGS];
int i, j;
for (i = 0; i < EGL_MAX_CONFIGS; i++)
ids[i] = i;
egl_config_sort(ids,
!sane && use_red, !sane && use_green,
!sane && use_blue, !sane && use_alpha);
/*
return configs
*/
j = 0;
for (i = 0; i < EGL_MAX_CONFIGS; i++) {
if (egl_config_filter(ids[i], attrib_list)) {
if (configs && j < config_size) {
configs[j] = egl_config_from_id(ids[i]);
j++;
} else if (!configs) {
// If configs==NULL then we count all configs
// Otherwise we only count the configs we return
j++;
}
}
}
thread->error = EGL_SUCCESS;
*num_config = j;
result = EGL_TRUE;
}
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
return choose_config(dpy, attrib_list, configs, config_size, num_config, false);
}
#if EGL_BRCM_sane_choose_config
EGLAPI EGLBoolean EGLAPIENTRY eglSaneChooseConfigBRCM(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
return choose_config(dpy, attrib_list, configs, config_size, num_config, true);
}
#endif
/*
EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
Khronos documentation:
3.4.3 Querying Configuration Attributes
To get the value of an EGLConfig attribute, use
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy,
EGLConfig config, EGLint attribute, EGLint
*value);
If eglGetConfigAttrib succeeds then it returns EGL_TRUE and the value for the
specified attribute is returned in value. Otherwise it returns EGL_FALSE. If attribute
is not a valid attribute then EGL_BAD_ATTRIBUTE is generated.
Refer to Table 3.1 and Table 3.4 for a list of valid EGL attributes.
EGL_BUFFER_SIZE integer depth of the color buffer
EGL_RED_SIZE integer bits of Red in the color buffer
EGL_GREEN_SIZE integer bits of Green in the color buffer
EGL_BLUE_SIZE integer bits of Blue in the color buffer
EGL_LUMINANCE_SIZE integer bits of Luminance in the color buffer
EGL_ALPHA_SIZE integer bits of Alpha in the color buffer
EGL_ALPHA_MASK_SIZE integer bits of Alpha Mask in the mask buffer
EGL_BIND_TO_TEXTURE_RGB boolean True if bindable to RGB textures.
EGL_BIND_TO_TEXTURE_RGBA boolean True if bindable to RGBA textures.
EGL_COLOR_BUFFER_TYPE enum color buffer type
EGL_CONFIG_CAVEAT enum any caveats for the configuration
EGL_CONFIG_ID integer unique EGLConfig identifier
EGL_CONFORMANT bitmask whether contexts created with this config are conformant
EGL_DEPTH_SIZE integer bits of Z in the depth buffer
EGL_LEVEL integer frame buffer level
EGL_MAX_PBUFFER_WIDTH integer maximum width of pbuffer
EGL_MAX_PBUFFER_HEIGHT integer maximum height of pbuffer
EGL_MAX_PBUFFER_PIXELS integer maximum size of pbuffer
EGL_MAX_SWAP_INTERVAL integer maximum swap interval
EGL_MIN_SWAP_INTERVAL integer minimum swap interval
EGL_NATIVE_RENDERABLE boolean EGL_TRUE if native rendering APIs can render to surface
EGL_NATIVE_VISUAL_ID integer handle of corresponding native visual
EGL_NATIVE_VISUAL_TYPE integer native visual type of the associated visual
EGL_RENDERABLE_TYPE bitmask which client APIs are supported
EGL_SAMPLE_BUFFERS integer number of multisample buffers
EGL_SAMPLES integer number of samples per pixel
EGL_STENCIL_SIZE integer bits of Stencil in the stencil buffer
EGL_SURFACE_TYPE bitmask which types of EGL surfaces are supported.
EGL_TRANSPARENT_TYPE enum type of transparency supported
EGL_TRANSPARENT_RED_VALUE integer transparent red value
EGL_TRANSPARENT_GREEN_VALUE integer transparent green value
EGL_TRANSPARENT_BLUE_VALUE integer transparent blue value
Preconditions:
value is null or a valid pointer
Postconditions:
The following conditions cause error to assume the specified value
EGL_BAD_DISPLAY An EGLDisplay argument does not name a valid EGLDisplay
EGL_NOT_INITIALIZED EGL is not initialized for the specified display.
EGL_BAD_PARAMETER value is null
EGL_BAD_CONFIG config does not name a valid EGLConfig
EGL_BAD_ATTRIBUTE attribute is not a valid attribute
EGL_SUCCESS Function succeeded.
if more than one condition holds, the first error is generated.
*/
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
{
CLIENT_THREAD_STATE_T *thread;
CLIENT_PROCESS_STATE_T *process;
EGLBoolean result;
if (CLIENT_LOCK_AND_GET_STATES(dpy, &thread, &process))
{
if (!value) {
thread->error = EGL_BAD_PARAMETER;
result = EGL_FALSE;
} else if (egl_config_to_id(config) < 0 || egl_config_to_id(config) >= EGL_MAX_CONFIGS) {
thread->error = EGL_BAD_CONFIG;
result = EGL_FALSE;
} else if (!egl_config_get_attrib(egl_config_to_id(config), attribute, value)) {
thread->error = EGL_BAD_ATTRIBUTE;
result = EGL_FALSE;
} else {
thread->error = EGL_SUCCESS;
result = EGL_TRUE;
}
CLIENT_UNLOCK();
}
else
result = EGL_FALSE;
return result;
}