Redo _eglInitSurface() so it can be used with all surface types.

Redo _eglInitContext() to do error checking, attribute list parsing, etc.
This commit is contained in:
Brian Paul 2005-11-27 23:57:19 +00:00
parent 49b2d2e90f
commit d548bf41d3
7 changed files with 278 additions and 183 deletions

View File

@ -303,7 +303,8 @@ _eglCompareConfigs(const _EGLConfig *a, const _EGLConfig *b)
* Typical fallback routine for eglChooseConfig
*/
EGLBoolean
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLConfig criteria;
@ -339,7 +340,8 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGL
* Fallback for eglGetConfigAttrib.
*/
EGLBoolean
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
EGLint attribute, EGLint *value)
{
const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
const EGLint k = attribute - FIRST_ATTRIB;
@ -358,7 +360,8 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint at
* Fallback for eglGetConfigs.
*/
EGLBoolean
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
EGLint config_size, EGLint *num_config)
{
_EGLDisplay *disp = _eglLookupDisplay(dpy);
@ -449,11 +452,12 @@ _eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint confi
*/
GLboolean
_eglFillInConfigs(_EGLConfig * configs,
GLenum fb_format, GLenum fb_type,
const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
int visType) {
GLenum fb_format, GLenum fb_type,
const u_int8_t * depth_bits, const u_int8_t * stencil_bits,
unsigned num_depth_stencil_bits,
const GLenum * db_modes, unsigned num_db_modes,
int visType)
{
static const u_int8_t bits_table[3][4] = {
/* R G B A */
{ 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */

View File

@ -3,6 +3,7 @@
#include <string.h>
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
#include "eglhash.h"
@ -12,11 +13,36 @@
/**
* Initialize the given _EGLContext object to defaults.
*/
void
_eglInitContext(_EGLContext *ctx)
EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list)
{
/* just init to zero for now */
_EGLConfig *conf;
_EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
return EGL_FALSE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
return EGL_NO_CONTEXT;
}
}
memset(ctx, 0, sizeof(_EGLContext));
ctx->Display = display;
ctx->Config = conf;
ctx->DrawSurface = EGL_NO_SURFACE;
ctx->ReadSurface = EGL_NO_SURFACE;
return EGL_TRUE;
}
@ -70,22 +96,24 @@ _eglGetCurrentContext(void)
* Just a placeholder/demo function. Real driver will never use this!
*/
EGLContext
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
EGLContext share_list, const EGLint *attrib_list)
{
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreateContext");
#if 0 /* example code */
_EGLContext *context;
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
return EGL_NO_CONTEXT;
if (!_eglInitContext(drv, dpy, context, config, attrib_list)) {
free(context);
return EGL_NO_CONTEXT;
}
if (share_list != EGL_NO_CONTEXT) {
_EGLContext *shareCtx = _eglLookupContext(share_list);
if (!shareCtx) {
_eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)");
return EGL_NO_CONTEXT;
}
}
_eglSaveContext(context);
return context->Handle;
#endif
return EGL_NO_CONTEXT;
}
@ -115,7 +143,8 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
EGLBoolean
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
EGLint attribute, EGLint *value)
{
_EGLContext *c = _eglLookupContext(ctx);
@ -144,7 +173,8 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribu
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d, EGLSurface r, EGLContext context)
_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
EGLSurface r, EGLContext context)
{
_EGLContext *ctx = _eglLookupContext(context);
_EGLSurface *draw = _eglLookupSurface(d);

View File

@ -25,8 +25,9 @@ struct _egl_context
};
extern void
_eglInitContext(_EGLContext *ctx);
extern EGLBoolean
_eglInitContext(_EGLDriver *drv, EGLDisplay dpy, _EGLContext *ctx,
EGLConfig config, const EGLint *attrib_list);
extern void

View File

@ -106,67 +106,30 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
/**
* Initialize the given _EGLSurface object. Do error checking.
* Assign it an EGLSurface handle and insert into hash table.
* \return EGLSurface handle or EGL_NO_SURFACE if error.
*/
EGLSurface
_eglInitScreenSurface(_EGLSurface *surf, _EGLDriver *drv, EGLDisplay dpy,
EGLConfig config, const EGLint *attrib_list)
{
EGLint width = 0, height = 0;
EGLint i;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
width = attrib_list[++i];
break;
case EGL_HEIGHT:
height = attrib_list[++i];
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateScreenSurfaceMESA");
return EGL_NO_SURFACE;
}
}
if (width <= 0 || height <= 0) {
_eglError(EGL_BAD_ATTRIBUTE,
"eglCreateScreenSurfaceMESA(width or height)");
return EGL_NO_SURFACE;
}
_eglInitSurface(surf);
surf->Width = width;
surf->Height = height;
surf->Type = EGL_SCREEN_BIT_MESA;
surf->Config = _eglLookupConfig(drv, dpy, config);
/* insert into hash table */
_eglSaveSurface(surf);
assert(surf->Handle);
return surf->Handle;
}
/**
* Create a drawing surface which can be directly displayed on a screen.
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
EGLSurface surface;
surf = (_EGLSurface *) malloc(sizeof(_EGLSurface));
surface = _eglInitScreenSurface(surf, drv, dpy, config, attrib_list);
if (surface == EGL_NO_SURFACE)
free(surf);
return surface;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_SCREEN_BIT_MESA,
config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}

View File

@ -6,6 +6,16 @@
* an integer.
*/
/**
* Per-screen information.
* Note that an EGL screen doesn't have a size. A screen may be set to
* one of several display modes (width/height/scanrate). The screen
* then displays a drawing surface. The drawing surface must be at least
* as large as the display mode's resolution. If it's larger, the
* OriginX and OriginY fields control what part of the surface is visible
* on the screen.
*/
struct _egl_screen
{
EGLScreenMESA Handle; /* The public/opaque handle which names this object */
@ -35,10 +45,6 @@ extern EGLBoolean
_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
extern EGLSurface
_eglInitScreenSurface(_EGLSurface *surf, _EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
extern EGLSurface
_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);

View File

@ -10,16 +10,134 @@
#include <string.h>
#include "eglcontext.h"
#include "eglconfig.h"
#include "eglsurface.h"
#include "eglglobals.h"
#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
void
_eglInitSurface(_EGLSurface *surf)
/**
* Do error check on parameters and initialize the given _EGLSurface object.
* \return EGL_TRUE if no errors, EGL_FALSE otherwise.
*/
EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list)
{
/* XXX fix this up */
const char *func;
_EGLConfig *conf;
EGLint width = 0, height = 0, largest = 0;
EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
EGLint i;
switch (type) {
case EGL_WINDOW_BIT:
func = "eglCreateWindowSurface";
break;
case EGL_PIXMAP_BIT:
func = "eglCreatePixmapSurface";
break;
case EGL_PBUFFER_BIT:
func = "eglCreatePBufferSurface";
break;
case EGL_SCREEN_BIT_MESA:
func = "eglCreateScreenSurface";
break;
default:
_eglLog(_EGL_WARNING, "Bad type in _eglInitSurface");
return EGL_FALSE;
}
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, func);
return EGL_FALSE;
}
/*
* Parse attribute list. Different kinds of surfaces support different
* attributes.
*/
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
width = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_HEIGHT:
if (type == EGL_PBUFFER_BIT || type == EGL_SCREEN_BIT_MESA) {
height = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_LARGEST_PBUFFER:
if (type == EGL_PBUFFER_BIT) {
largest = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_TEXTURE_FORMAT:
if (type == EGL_PBUFFER_BIT) {
texFormat = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_TEXTURE_TARGET:
if (type == EGL_PBUFFER_BIT) {
texTarget = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
case EGL_MIPMAP_TEXTURE:
if (type == EGL_PBUFFER_BIT) {
mipmapTex = attrib_list[++i];
}
else {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
}
if (width <= 0 || height <= 0) {
_eglError(EGL_BAD_ATTRIBUTE, func);
return EGL_FALSE;
}
memset(surf, 0, sizeof(_EGLSurface));
surf->Config = conf;
surf->Type = type;
surf->Width = width;
surf->Height = height;
surf->TextureFormat = texFormat;
surf->TextureTarget = texTarget;
surf->MipmapTexture = mipmapTex;
surf->MipmapLevel = 0;
surf->SwapInterval = 0;
return EGL_TRUE;
}
@ -27,7 +145,9 @@ void
_eglSaveSurface(_EGLSurface *surf)
{
assert(surf);
assert(!surf->Handle);
surf->Handle = _eglHashGenKey(_eglGlobal.Contexts);
assert(surf->Handle);
_eglHashInsert(_eglGlobal.Surfaces, surf->Handle, surf);
}
@ -86,7 +206,8 @@ _eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
EGLBoolean
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
NativePixmapType target)
{
/* copy surface to native pixmap */
/* All implementation burdon for this is in the device driver */
@ -95,7 +216,8 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixma
EGLBoolean
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attribute, EGLint *value)
_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLint attribute, EGLint *value)
{
_EGLSurface *surface = _eglLookupSurface(surf);
if (surface == NULL) {
@ -140,34 +262,82 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf, EGLint attrib
/**
* Default fallback routine - drivers should usually override this.
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
NativeWindowType window, const EGLint *attrib_list)
{
/* nothing - just a placeholder */
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_WINDOW_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Default fallback routine - drivers should usually override this.
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
NativePixmapType pixmap, const EGLint *attrib_list)
{
/* nothing - just a placeholder */
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PIXMAP_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
/**
* Default fallback routine - drivers should usually override this.
* Example function - drivers should do a proper implementation.
*/
EGLSurface
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
const EGLint *attrib_list)
{
/* nothing - just a placeholder */
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
return EGL_NO_SURFACE;
if (!_eglInitSurface(drv, dpy, surf, EGL_PBUFFER_BIT, config, attrib_list)) {
free(surf);
return EGL_NO_SURFACE;
}
_eglSaveSurface(surf);
return surf->Handle;
#endif
return EGL_NO_SURFACE;
}
@ -248,79 +418,3 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
surf->SwapInterval = interval;
return EGL_TRUE;
}
/**
** EGL Surface Utility Functions. This could be handy for device drivers.
**/
/**
* Initialize the fields of the given _EGLSurface object from the other
* parameters. Do error checking too. Allocate EGLSurface handle and
* insert into hash table.
* \return EGLSurface handle or EGL_NO_SURFACE if any error
*/
EGLSurface
_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy,
EGLConfig config, const EGLint *attrib_list)
{
_EGLConfig *conf;
EGLint width = 0, height = 0, largest = 0;
EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
EGLint i;
conf = _eglLookupConfig(drv, dpy, config);
if (!conf) {
_eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
case EGL_WIDTH:
width = attrib_list[++i];
break;
case EGL_HEIGHT:
height = attrib_list[++i];
break;
case EGL_LARGEST_PBUFFER:
largest = attrib_list[++i];
break;
case EGL_TEXTURE_FORMAT:
texFormat = attrib_list[++i];
break;
case EGL_TEXTURE_TARGET:
texTarget = attrib_list[++i];
break;
case EGL_MIPMAP_TEXTURE:
mipmapTex = attrib_list[++i];
break;
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
return EGL_NO_SURFACE;
}
}
if (width <= 0 || height <= 0) {
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface(width or height)");
return EGL_NO_SURFACE;
}
surface->Config = conf;
surface->Type = EGL_PBUFFER_BIT;
surface->Width = width;
surface->Height = height;
surface->TextureFormat = texFormat;
surface->TextureTarget = texTarget;
surface->MipmapTexture = mipmapTex;
surface->MipmapLevel = 0;
surface->SwapInterval = 0;
/* insert into hash table */
_eglSaveSurface(surface);
assert(surface->Handle);
return surface->Handle;
}

View File

@ -28,8 +28,10 @@ struct _egl_surface
};
extern void
_eglInitSurface(_EGLSurface *surf);
extern EGLBoolean
_eglInitSurface(_EGLDriver *drv, EGLDisplay dpy,
_EGLSurface *surf, EGLint type, EGLConfig config,
const EGLint *attrib_list);
extern void
@ -92,9 +94,4 @@ extern EGLBoolean
_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
extern EGLSurface
_eglInitPbufferSurface(_EGLSurface *surface, _EGLDriver *drv, EGLDisplay dpy,
EGLConfig config, const EGLint *attrib_list);
#endif /* EGLSURFACE_INCLUDED */