mesa/src/egl/main/eglsurface.c

808 lines
24 KiB
C
Raw Normal View History

/**************************************************************************
*
* Copyright 2008 VMware, Inc.
* Copyright 2009-2010 Chia-I Wu <olvaffe@gmail.com>
* Copyright 2010 LunarG, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
2005-04-22 22:09:39 +01:00
/**
* Surface-related functions.
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "egldefines.h"
#include "egldisplay.h"
#include "egldriver.h"
2005-04-22 22:09:39 +01:00
#include "eglcontext.h"
#include "eglconfig.h"
#include "eglcurrent.h"
#include "egllog.h"
#include "eglsurface.h"
2005-04-22 22:09:39 +01:00
#include "util/macros.h"
2005-04-22 22:09:39 +01:00
/**
* Parse the list of surface attributes and return the proper error code.
*/
static EGLint
_eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
{
_EGLDisplay *disp = surf->Resource.Display;
EGLint type = surf->Type;
EGLint texture_type = EGL_PBUFFER_BIT;
EGLint i, err = EGL_SUCCESS;
EGLint attr = EGL_NONE;
EGLint val = EGL_NONE;
if (!attrib_list)
return EGL_SUCCESS;
if (disp->Extensions.NOK_texture_from_pixmap)
texture_type |= EGL_PIXMAP_BIT;
for (i = 0; attrib_list[i] != EGL_NONE; i++) {
attr = attrib_list[i++];
val = attrib_list[i];
switch (attr) {
/* common attributes */
case EGL_GL_COLORSPACE_KHR:
if (!disp->Extensions.KHR_gl_colorspace) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) {
case EGL_GL_COLORSPACE_SRGB_KHR:
case EGL_GL_COLORSPACE_LINEAR_KHR:
break;
default:
err = EGL_BAD_ATTRIBUTE;
}
if (err != EGL_SUCCESS)
break;
surf->GLColorspace = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_r.x = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_r.y = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_g.x = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_g.y = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_b.x = val;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.display_primary_b.y = val;
break;
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.white_point.x = val;
break;
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.white_point.y = val;
break;
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.max_luminance = val;
break;
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
if (!disp->Extensions.EXT_surface_SMPTE2086_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.min_luminance = val;
break;
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.max_cll = val;
break;
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
if (!disp->Extensions.EXT_surface_CTA861_3_metadata) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->HdrMetadata.max_fall = val;
break;
case EGL_VG_COLORSPACE:
switch (val) {
case EGL_VG_COLORSPACE_sRGB:
case EGL_VG_COLORSPACE_LINEAR:
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surf->VGColorspace = val;
break;
case EGL_VG_ALPHA_FORMAT:
switch (val) {
case EGL_VG_ALPHA_FORMAT_NONPRE:
case EGL_VG_ALPHA_FORMAT_PRE:
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surf->VGAlphaFormat = val;
break;
/* window surface attributes */
case EGL_RENDER_BUFFER:
if (type != EGL_WINDOW_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (val != EGL_BACK_BUFFER && val != EGL_SINGLE_BUFFER) {
err = EGL_BAD_ATTRIBUTE;
break;
}
egl: Simplify queries for EGL_RENDER_BUFFER There exist *two* queryable EGL_RENDER_BUFFER states in EGL: eglQuerySurface(EGL_RENDER_BUFFER) and eglQueryContext(EGL_RENDER_BUFFER). These changes eliminate potentially very fragile code in the upcoming EGL_KHR_mutable_render_buffer implementation. * eglQuerySurface(EGL_RENDER_BUFFER) The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained abstruse logic which required comprehending the specification complexities of how the two EGL_RENDER_BUFFER states interact. The function sometimes returned _EGLContext::WindowRenderBuffer, sometimes _EGLSurface::RenderBuffer. Why? The function tried to encode the actual logic from the EGL spec. When did the function return which variable? Go study the EGL spec, hope you understand it, then hope Mesa mutated the EGL_RENDER_BUFFER state in all the correct places. Have fun. To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::RequestedRenderBuffer. Nothing difficult here. * eglQueryContext(EGL_RENDER_BUFFER) The implementation of this suffered from the same issues as eglQuerySurface, and the solution is the same. confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::ActiveRenderBuffer. Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
surf->RequestedRenderBuffer = val;
if (surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR) {
/* Unlike normal EGLSurfaces, one with a mutable render buffer
* uses the application-chosen render buffer.
*/
surf->ActiveRenderBuffer = val;
}
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
if (!disp->Extensions.NV_post_sub_buffer ||
type != EGL_WINDOW_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (val != EGL_TRUE && val != EGL_FALSE) {
err = EGL_BAD_PARAMETER;
break;
}
surf->PostSubBufferSupportedNV = val;
break;
/* pbuffer surface attributes */
case EGL_WIDTH:
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (val < 0) {
err = EGL_BAD_PARAMETER;
break;
}
surf->Width = val;
break;
case EGL_HEIGHT:
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (val < 0) {
err = EGL_BAD_PARAMETER;
break;
}
surf->Height = val;
break;
case EGL_LARGEST_PBUFFER:
if (type != EGL_PBUFFER_BIT) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->LargestPbuffer = !!val;
break;
/* for eglBindTexImage */
case EGL_TEXTURE_FORMAT:
if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) {
case EGL_TEXTURE_RGB:
case EGL_TEXTURE_RGBA:
case EGL_NO_TEXTURE:
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surf->TextureFormat = val;
break;
case EGL_TEXTURE_TARGET:
if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
switch (val) {
case EGL_TEXTURE_2D:
case EGL_NO_TEXTURE:
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surf->TextureTarget = val;
break;
case EGL_MIPMAP_TEXTURE:
if (!(type & texture_type)) {
err = EGL_BAD_ATTRIBUTE;
break;
}
surf->MipmapTexture = !!val;
break;
/* no pixmap surface specific attributes */
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
}
if (err == EGL_SUCCESS && type == EGL_PBUFFER_BIT) {
if ((surf->TextureTarget == EGL_NO_TEXTURE && surf->TextureFormat != EGL_NO_TEXTURE) ||
(surf->TextureFormat == EGL_NO_TEXTURE && surf->TextureTarget != EGL_NO_TEXTURE)) {
attr = surf->TextureTarget == EGL_NO_TEXTURE ? EGL_TEXTURE_TARGET : EGL_TEXTURE_FORMAT;
err = EGL_BAD_MATCH;
}
}
if (err != EGL_SUCCESS)
_eglLog(_EGL_WARNING, "bad surface attribute 0x%04x", attr);
return err;
}
/**
* Do error check on parameters and initialize the given _EGLSurface object.
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
_eglInitSurface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type,
_EGLConfig *conf, const EGLint *attrib_list,
void *native_surface)
2005-04-22 22:09:39 +01:00
{
const char *func;
2006-01-30 00:10:55 +00:00
EGLint renderBuffer = EGL_BACK_BUFFER;
EGLint swapBehavior = EGL_BUFFER_DESTROYED;
EGLint err;
/* Swap behavior can be preserved only if config supports this. */
if (conf->SurfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
swapBehavior = EGL_BUFFER_PRESERVED;
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
swapBehavior = EGL_BUFFER_DESTROYED;
break;
case EGL_PIXMAP_BIT:
func = "eglCreatePixmapSurface";
2006-01-30 00:10:55 +00:00
renderBuffer = EGL_SINGLE_BUFFER;
break;
case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface";
break;
default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
return EGL_FALSE;
}
if ((conf->SurfaceType & type) == 0)
/* The config can't be used to create a surface of this type */
return _eglError(EGL_BAD_MATCH, func);
_eglInitResource(&surf->Resource, sizeof(*surf), disp);
surf->Type = type;
surf->Config = conf;
surf->Lost = EGL_FALSE;
surf->Width = 0;
surf->Height = 0;
surf->TextureFormat = EGL_NO_TEXTURE;
surf->TextureTarget = EGL_NO_TEXTURE;
surf->MipmapTexture = EGL_FALSE;
surf->LargestPbuffer = EGL_FALSE;
egl: Simplify queries for EGL_RENDER_BUFFER There exist *two* queryable EGL_RENDER_BUFFER states in EGL: eglQuerySurface(EGL_RENDER_BUFFER) and eglQueryContext(EGL_RENDER_BUFFER). These changes eliminate potentially very fragile code in the upcoming EGL_KHR_mutable_render_buffer implementation. * eglQuerySurface(EGL_RENDER_BUFFER) The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained abstruse logic which required comprehending the specification complexities of how the two EGL_RENDER_BUFFER states interact. The function sometimes returned _EGLContext::WindowRenderBuffer, sometimes _EGLSurface::RenderBuffer. Why? The function tried to encode the actual logic from the EGL spec. When did the function return which variable? Go study the EGL spec, hope you understand it, then hope Mesa mutated the EGL_RENDER_BUFFER state in all the correct places. Have fun. To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::RequestedRenderBuffer. Nothing difficult here. * eglQueryContext(EGL_RENDER_BUFFER) The implementation of this suffered from the same issues as eglQuerySurface, and the solution is the same. confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::ActiveRenderBuffer. Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
surf->RequestedRenderBuffer = renderBuffer;
surf->ActiveRenderBuffer = renderBuffer;
surf->VGAlphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
surf->VGColorspace = EGL_VG_COLORSPACE_sRGB;
surf->GLColorspace = EGL_GL_COLORSPACE_LINEAR_KHR;
surf->MipmapLevel = 0;
surf->MultisampleResolve = EGL_MULTISAMPLE_RESOLVE_DEFAULT;
surf->SwapBehavior = swapBehavior;
surf->HorizontalResolution = EGL_UNKNOWN;
surf->VerticalResolution = EGL_UNKNOWN;
surf->AspectRatio = EGL_UNKNOWN;
surf->PostSubBufferSupportedNV = EGL_FALSE;
surf->SetDamageRegionCalled = EGL_FALSE;
surf->BufferAgeRead = EGL_FALSE;
/* the default swap interval is 1 */
surf->SwapInterval = 1;
surf->HdrMetadata.display_primary_r.x = EGL_DONT_CARE;
surf->HdrMetadata.display_primary_r.y = EGL_DONT_CARE;
surf->HdrMetadata.display_primary_g.x = EGL_DONT_CARE;
surf->HdrMetadata.display_primary_g.y = EGL_DONT_CARE;
surf->HdrMetadata.display_primary_b.x = EGL_DONT_CARE;
surf->HdrMetadata.display_primary_b.y = EGL_DONT_CARE;
surf->HdrMetadata.white_point.x = EGL_DONT_CARE;
surf->HdrMetadata.white_point.y = EGL_DONT_CARE;
surf->HdrMetadata.max_luminance = EGL_DONT_CARE;
surf->HdrMetadata.min_luminance = EGL_DONT_CARE;
surf->HdrMetadata.max_cll = EGL_DONT_CARE;
surf->HdrMetadata.max_fall = EGL_DONT_CARE;
err = _eglParseSurfaceAttribList(surf, attrib_list);
if (err != EGL_SUCCESS)
return _eglError(err, func);
/* if EGL_LARGEST_PBUFFER in use, clamp width and height */
if (surf->LargestPbuffer) {
surf->Width = MIN2(surf->Width, _EGL_MAX_PBUFFER_WIDTH);
surf->Height = MIN2(surf->Height, _EGL_MAX_PBUFFER_HEIGHT);
}
surf->NativeSurface = native_surface;
return EGL_TRUE;
2005-04-22 22:09:39 +01:00
}
EGLBoolean
_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
EGLint attribute, EGLint *value)
2005-04-22 22:09:39 +01:00
{
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
break;
2005-04-22 22:09:39 +01:00
case EGL_HEIGHT:
*value = surface->Height;
break;
2005-04-22 22:09:39 +01:00
case EGL_CONFIG_ID:
*value = surface->Config->ConfigID;
break;
case EGL_LARGEST_PBUFFER:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->LargestPbuffer;
break;
2005-04-22 22:09:39 +01:00
case EGL_TEXTURE_FORMAT:
/* texture attributes: only for pbuffers, no error otherwise */
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureFormat;
break;
2005-04-22 22:09:39 +01:00
case EGL_TEXTURE_TARGET:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->TextureTarget;
break;
2005-04-22 22:09:39 +01:00
case EGL_MIPMAP_TEXTURE:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapTexture;
break;
2005-04-22 22:09:39 +01:00
case EGL_MIPMAP_LEVEL:
if (surface->Type == EGL_PBUFFER_BIT)
*value = surface->MipmapLevel;
break;
2006-01-30 00:10:55 +00:00
case EGL_SWAP_BEHAVIOR:
*value = surface->SwapBehavior;
break;
2006-01-30 00:10:55 +00:00
case EGL_RENDER_BUFFER:
/* From the EGL_KHR_mutable_render_buffer spec (v12):
egl: Simplify queries for EGL_RENDER_BUFFER There exist *two* queryable EGL_RENDER_BUFFER states in EGL: eglQuerySurface(EGL_RENDER_BUFFER) and eglQueryContext(EGL_RENDER_BUFFER). These changes eliminate potentially very fragile code in the upcoming EGL_KHR_mutable_render_buffer implementation. * eglQuerySurface(EGL_RENDER_BUFFER) The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained abstruse logic which required comprehending the specification complexities of how the two EGL_RENDER_BUFFER states interact. The function sometimes returned _EGLContext::WindowRenderBuffer, sometimes _EGLSurface::RenderBuffer. Why? The function tried to encode the actual logic from the EGL spec. When did the function return which variable? Go study the EGL spec, hope you understand it, then hope Mesa mutated the EGL_RENDER_BUFFER state in all the correct places. Have fun. To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::RequestedRenderBuffer. Nothing difficult here. * eglQueryContext(EGL_RENDER_BUFFER) The implementation of this suffered from the same issues as eglQuerySurface, and the solution is the same. confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::ActiveRenderBuffer. Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
*
* Querying EGL_RENDER_BUFFER returns the buffer which client API
* rendering is requested to use. For a window surface, this is the
* attribute value specified when the surface was created or last set
* via eglSurfaceAttrib.
*
* In other words, querying a window surface returns the value most
* recently *requested* by the user.
*
* The paragraph continues in the EGL 1.5 spec (2014.08.27):
*
* For a pbuffer surface, it is always EGL_BACK_BUFFER . For a pixmap
egl: Simplify queries for EGL_RENDER_BUFFER There exist *two* queryable EGL_RENDER_BUFFER states in EGL: eglQuerySurface(EGL_RENDER_BUFFER) and eglQueryContext(EGL_RENDER_BUFFER). These changes eliminate potentially very fragile code in the upcoming EGL_KHR_mutable_render_buffer implementation. * eglQuerySurface(EGL_RENDER_BUFFER) The implementation of eglQuerySurface(EGL_RENDER_BUFFER) contained abstruse logic which required comprehending the specification complexities of how the two EGL_RENDER_BUFFER states interact. The function sometimes returned _EGLContext::WindowRenderBuffer, sometimes _EGLSurface::RenderBuffer. Why? The function tried to encode the actual logic from the EGL spec. When did the function return which variable? Go study the EGL spec, hope you understand it, then hope Mesa mutated the EGL_RENDER_BUFFER state in all the correct places. Have fun. To simplify eglQuerySurface(EGL_RENDER_BUFFER), and to improve confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::RequestedRenderBuffer. Nothing difficult here. * eglQueryContext(EGL_RENDER_BUFFER) The implementation of this suffered from the same issues as eglQuerySurface, and the solution is the same. confidence in its correctness, flatten its indirect logic. For pixmap and pbuffer surfaces, simply return a hard-coded literal value, as the spec suggests. For window surfaces, simply return _EGLSurface::ActiveRenderBuffer. Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
2018-04-07 22:23:48 +01:00
* surface, it is always EGL_SINGLE_BUFFER . To determine the actual
* buffer being rendered to by a context, call eglQueryContext.
*/
switch (surface->Type) {
default:
unreachable("bad EGLSurface type");
case EGL_WINDOW_BIT:
*value = surface->RequestedRenderBuffer;
break;
case EGL_PBUFFER_BIT:
*value = EGL_BACK_BUFFER;
break;
case EGL_PIXMAP_BIT:
*value = EGL_SINGLE_BUFFER;
break;
}
break;
2006-01-30 00:10:55 +00:00
case EGL_PIXEL_ASPECT_RATIO:
*value = surface->AspectRatio;
break;
2006-01-30 00:10:55 +00:00
case EGL_HORIZONTAL_RESOLUTION:
*value = surface->HorizontalResolution;
break;
2006-01-30 00:10:55 +00:00
case EGL_VERTICAL_RESOLUTION:
*value = surface->VerticalResolution;
break;
case EGL_MULTISAMPLE_RESOLVE:
*value = surface->MultisampleResolve;
break;
case EGL_VG_ALPHA_FORMAT:
*value = surface->VGAlphaFormat;
break;
case EGL_VG_COLORSPACE:
*value = surface->VGColorspace;
break;
case EGL_GL_COLORSPACE_KHR:
if (!disp->Extensions.KHR_gl_colorspace)
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
*value = surface->GLColorspace;
break;
case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
*value = surface->PostSubBufferSupportedNV;
break;
case EGL_BUFFER_AGE_EXT:
/* Both EXT_buffer_age and KHR_partial_update accept EGL_BUFFER_AGE_EXT.
* To be precise, the KHR one accepts EGL_BUFFER_AGE_KHR which is an
* alias with the same numeric value.
*/
if (!disp->Extensions.EXT_buffer_age &&
!disp->Extensions.KHR_partial_update)
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
_EGLContext *ctx = _eglGetCurrentContext();
EGLint result = drv->API.QueryBufferAge(drv, disp, surface);
/* error happened */
if (result < 0)
return EGL_FALSE;
if (_eglGetContextHandle(ctx) == EGL_NO_CONTEXT ||
ctx->DrawSurface != surface)
return _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
*value = result;
surface->BufferAgeRead = EGL_TRUE;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
*value = surface->HdrMetadata.display_primary_r.x;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
*value = surface->HdrMetadata.display_primary_r.y;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
*value = surface->HdrMetadata.display_primary_g.x;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
*value = surface->HdrMetadata.display_primary_g.y;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
*value = surface->HdrMetadata.display_primary_b.x;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
*value = surface->HdrMetadata.display_primary_b.y;
break;
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
*value = surface->HdrMetadata.white_point.x;
break;
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
*value = surface->HdrMetadata.white_point.y;
break;
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
*value = surface->HdrMetadata.max_luminance;
break;
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
*value = surface->HdrMetadata.min_luminance;
break;
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
*value = surface->HdrMetadata.max_cll;
break;
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
*value = surface->HdrMetadata.max_fall;
break;
2005-04-22 22:09:39 +01:00
default:
return _eglError(EGL_BAD_ATTRIBUTE, "eglQuerySurface");
2005-04-22 22:09:39 +01:00
}
return EGL_TRUE;
2005-04-22 22:09:39 +01:00
}
/**
* Default fallback routine - drivers might override this.
*/
EGLBoolean
_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
EGLint attribute, EGLint value)
2005-04-22 22:09:39 +01:00
{
EGLint confval;
EGLint err = EGL_SUCCESS;
EGLint all_es_bits = EGL_OPENGL_ES_BIT |
EGL_OPENGL_ES2_BIT |
EGL_OPENGL_ES3_BIT_KHR;
2005-04-22 22:09:39 +01:00
switch (attribute) {
case EGL_MIPMAP_LEVEL:
confval = surface->Config->RenderableType;
if (!(confval & all_es_bits)) {
err = EGL_BAD_PARAMETER;
break;
}
2005-04-22 22:09:39 +01:00
surface->MipmapLevel = value;
break;
case EGL_MULTISAMPLE_RESOLVE:
switch (value) {
case EGL_MULTISAMPLE_RESOLVE_DEFAULT:
break;
case EGL_MULTISAMPLE_RESOLVE_BOX:
confval = surface->Config->SurfaceType;
if (!(confval & EGL_MULTISAMPLE_RESOLVE_BOX_BIT))
err = EGL_BAD_MATCH;
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surface->MultisampleResolve = value;
break;
case EGL_RENDER_BUFFER:
if (!disp->Extensions.KHR_mutable_render_buffer) {
err = EGL_BAD_ATTRIBUTE;
break;
}
if (value != EGL_BACK_BUFFER && value != EGL_SINGLE_BUFFER) {
err = EGL_BAD_PARAMETER;
break;
}
/* From the EGL_KHR_mutable_render_buffer spec (v12):
*
* If attribute is EGL_RENDER_BUFFER, and the EGL_SURFACE_TYPE
* attribute of the EGLConfig used to create surface does not contain
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR, [...] an EGL_BAD_MATCH error is
* generated [...].
*/
if (!(surface->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR)) {
err = EGL_BAD_MATCH;
break;
}
surface->RequestedRenderBuffer = value;
break;
case EGL_SWAP_BEHAVIOR:
switch (value) {
case EGL_BUFFER_DESTROYED:
break;
case EGL_BUFFER_PRESERVED:
confval = surface->Config->SurfaceType;
if (!(confval & EGL_SWAP_BEHAVIOR_PRESERVED_BIT))
err = EGL_BAD_MATCH;
break;
default:
err = EGL_BAD_ATTRIBUTE;
break;
}
if (err != EGL_SUCCESS)
break;
surface->SwapBehavior = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT:
surface->HdrMetadata.display_primary_r.x = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT:
surface->HdrMetadata.display_primary_r.y = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT:
surface->HdrMetadata.display_primary_g.x = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT:
surface->HdrMetadata.display_primary_g.y = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT:
surface->HdrMetadata.display_primary_b.x = value;
break;
case EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT:
surface->HdrMetadata.display_primary_b.y = value;
break;
case EGL_SMPTE2086_WHITE_POINT_X_EXT:
surface->HdrMetadata.white_point.x = value;
break;
case EGL_SMPTE2086_WHITE_POINT_Y_EXT:
surface->HdrMetadata.white_point.y = value;
break;
case EGL_SMPTE2086_MAX_LUMINANCE_EXT:
surface->HdrMetadata.max_luminance = value;
break;
case EGL_SMPTE2086_MIN_LUMINANCE_EXT:
surface->HdrMetadata.min_luminance = value;
break;
case EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT:
surface->HdrMetadata.max_cll = value;
break;
case EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT:
surface->HdrMetadata.max_fall = value;
break;
2005-04-22 22:09:39 +01:00
default:
err = EGL_BAD_ATTRIBUTE;
break;
2005-04-22 22:09:39 +01:00
}
if (err != EGL_SUCCESS)
return _eglError(err, "eglSurfaceAttrib");
2005-04-22 22:09:39 +01:00
return EGL_TRUE;
}
EGLBoolean
_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surface,
EGLint buffer)
2005-04-22 22:09:39 +01:00
{
EGLint texture_type = EGL_PBUFFER_BIT;
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
if (disp->Extensions.NOK_texture_from_pixmap)
texture_type |= EGL_PIXMAP_BIT;
if (!(surface->Type & texture_type))
return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
if (surface->TextureFormat == EGL_NO_TEXTURE)
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
if (surface->TextureTarget == EGL_NO_TEXTURE)
return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
surface->BoundToTexture = EGL_TRUE;
return EGL_TRUE;
2005-04-22 22:09:39 +01:00
}
EGLBoolean
_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint buffer)
{
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
EGLint texture_type = EGL_PBUFFER_BIT;
if (surf == EGL_NO_SURFACE)
return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
if (!surf->BoundToTexture)
{
/* Not an error, simply nothing to do */
return EGL_TRUE;
}
if (surf->TextureFormat == EGL_NO_TEXTURE)
return _eglError(EGL_BAD_MATCH, "eglReleaseTexImage");
if (buffer != EGL_BACK_BUFFER)
return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
if (disp->Extensions.NOK_texture_from_pixmap)
texture_type |= EGL_PIXMAP_BIT;
if (!(surf->Type & texture_type))
return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
surf->BoundToTexture = EGL_FALSE;
return EGL_TRUE;
}
2005-04-22 22:09:39 +01:00
EGLBoolean
_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint interval)
2005-04-22 22:09:39 +01:00
{
return EGL_TRUE;
}
EGLBoolean
_eglSurfaceHasMutableRenderBuffer(_EGLSurface *surf)
{
return surf->Type == EGL_WINDOW_BIT &&
surf->Config &&
(surf->Config->SurfaceType & EGL_MUTABLE_RENDER_BUFFER_BIT_KHR);
}
EGLBoolean
_eglSurfaceInSharedBufferMode(_EGLSurface *surf)
{
return _eglSurfaceHasMutableRenderBuffer(surf) &&
surf->ActiveRenderBuffer == EGL_SINGLE_BUFFER;
}