mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-23 06:10:23 +01:00
egl: new EGL/gallium/softpipe/xlib winsys
Checkpoint commit. Most required code is in place, and compiles, but totally untested.
This commit is contained in:
parent
1c73b4ba86
commit
bee79eb9b9
4 changed files with 832 additions and 0 deletions
87
src/gallium/winsys/egl_xlib/Makefile
Normal file
87
src/gallium/winsys/egl_xlib/Makefile
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# src/gallium/winsys/egl_xlib/Makefile
|
||||
|
||||
# Build softpipe/xlib/EGL driver library/object: "softpipe_egl.so"
|
||||
|
||||
|
||||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
|
||||
LIBNAME = softpipe_egl.so
|
||||
|
||||
|
||||
INCLUDE_DIRS = \
|
||||
-I$(TOP)/include \
|
||||
-I$(TOP)/src/egl/main \
|
||||
-I$(TOP)/src/mesa \
|
||||
-I$(TOP)/src/mesa/main \
|
||||
-I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/src/gallium/auxiliary
|
||||
|
||||
WINSYS_SOURCES = \
|
||||
egl_xlib.c \
|
||||
sw_winsys.c
|
||||
|
||||
WINSYS_OBJECTS = $(WINSYS_SOURCES:.c=.o)
|
||||
|
||||
|
||||
LIBS = \
|
||||
$(GALLIUM_DRIVERS) \
|
||||
$(TOP)/src/mesa/libglapi.a \
|
||||
$(TOP)/src/mesa/libmesa.a \
|
||||
$(GALLIUM_AUXILIARIES)
|
||||
|
||||
|
||||
LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1
|
||||
|
||||
|
||||
.SUFFIXES : .cpp
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(LOCAL_CFLAGS) $< -o $@
|
||||
|
||||
.cpp.o:
|
||||
$(CXX) -c $(INCLUDE_DIRS) $(CXXFLAGS) $(LOCAL_CFLAGS) $< -o $@
|
||||
|
||||
|
||||
|
||||
default: $(TOP)/$(LIB_DIR)/$(LIBNAME)
|
||||
|
||||
|
||||
# Make the softpipe_egl.so library
|
||||
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(WINSYS_OBJECTS) $(LIBS)
|
||||
$(TOP)/bin/mklib -o $(LIBNAME) \
|
||||
-linker "$(CC)" \
|
||||
-noprefix \
|
||||
-install $(TOP)/$(LIB_DIR) \
|
||||
$(MKLIB_OPTIONS) $(WINSYS_OBJECTS) \
|
||||
--start-group $(LIBS) --end-group
|
||||
|
||||
# $(GL_LIB_DEPS)
|
||||
|
||||
|
||||
depend: $(ALL_SOURCES)
|
||||
@ echo "running $(MKDEP)"
|
||||
@ rm -f depend # workaround oops on gutsy?!?
|
||||
@ touch depend
|
||||
@ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDE_DIRS) $(ALL_SOURCES) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
install: default
|
||||
$(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
|
||||
@if [ -e $(TOP)/$(LIB_DIR) ]; then \
|
||||
$(INSTALL) $(TOP)/$(LIB_DIR)/$(LIBNAME) $(INSTALL_DIR)/$(LIB_DIR); \
|
||||
fi
|
||||
|
||||
|
||||
# Emacs tags
|
||||
tags:
|
||||
etags `find . -name \*.[ch]` $(TOP)/include/GL/*.h
|
||||
|
||||
clean:
|
||||
-rm -f *.o *~ *.bak
|
||||
|
||||
|
||||
include depend
|
||||
461
src/gallium/winsys/egl_xlib/egl_xlib.c
Normal file
461
src/gallium/winsys/egl_xlib/egl_xlib.c
Normal file
|
|
@ -0,0 +1,461 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* EGL / softpipe / xlib winsys module
|
||||
*
|
||||
* Authors: Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "softpipe/sp_winsys.h"
|
||||
|
||||
#include "eglconfig.h"
|
||||
#include "eglconfigutil.h"
|
||||
#include "eglcontext.h"
|
||||
#include "egldisplay.h"
|
||||
#include "egldriver.h"
|
||||
#include "eglglobals.h"
|
||||
#include "egllog.h"
|
||||
#include "eglsurface.h"
|
||||
|
||||
#include "state_tracker/st_public.h"
|
||||
|
||||
#include "sw_winsys.h"
|
||||
|
||||
|
||||
/** subclass of _EGLDriver */
|
||||
struct xlib_egl_driver
|
||||
{
|
||||
_EGLDriver Base; /**< base class */
|
||||
|
||||
struct pipe_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
};
|
||||
|
||||
|
||||
/** subclass of _EGLContext */
|
||||
struct xlib_egl_context
|
||||
{
|
||||
_EGLContext Base; /**< base class */
|
||||
|
||||
struct pipe_context *pipe; /**< Gallium driver context */
|
||||
struct st_context *Context; /**< Mesa/gallium state tracker context */
|
||||
};
|
||||
|
||||
|
||||
/** subclass of _EGLSurface */
|
||||
struct xlib_egl_surface
|
||||
{
|
||||
_EGLSurface Base; /**< base class */
|
||||
|
||||
Display *Dpy; /**< The X Display of the window */
|
||||
Window Win; /**< The user-created window ID */
|
||||
GC Gc;
|
||||
XVisualInfo VisInfo;
|
||||
|
||||
struct pipe_winsys *winsys;
|
||||
|
||||
struct st_framebuffer *Framebuffer;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct xlib_egl_driver *
|
||||
xlib_egl_driver(_EGLDriver *drv)
|
||||
{
|
||||
return (struct xlib_egl_driver *) drv;
|
||||
}
|
||||
|
||||
|
||||
static struct xlib_egl_surface *
|
||||
lookup_surface(EGLSurface surf)
|
||||
{
|
||||
_EGLSurface *surface = _eglLookupSurface(surf);
|
||||
return (struct xlib_egl_surface *) surface;
|
||||
}
|
||||
|
||||
|
||||
static struct xlib_egl_context *
|
||||
lookup_context(EGLContext surf)
|
||||
{
|
||||
_EGLContext *context = _eglLookupContext(surf);
|
||||
return (struct xlib_egl_context *) context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* XXX temporary
|
||||
* Need to query X server's GLX visuals.
|
||||
*/
|
||||
static void
|
||||
init_configs(_EGLDriver *drv, EGLDisplay dpy)
|
||||
{
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
_EGLConfig config;
|
||||
int id = i + 1;
|
||||
_eglInitConfig(&config, id);
|
||||
SET_CONFIG_ATTRIB(&config, EGL_RED_SIZE, 8);
|
||||
SET_CONFIG_ATTRIB(&config, EGL_GREEN_SIZE, 8);
|
||||
SET_CONFIG_ATTRIB(&config, EGL_BLUE_SIZE, 8);
|
||||
SET_CONFIG_ATTRIB(&config, EGL_ALPHA_SIZE, 8);
|
||||
if (i > 0) {
|
||||
SET_CONFIG_ATTRIB(&config, EGL_DEPTH_SIZE, 24);
|
||||
SET_CONFIG_ATTRIB(&config, EGL_STENCIL_SIZE, 8);
|
||||
}
|
||||
_eglAddConfig(disp, &config);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglInitialize(), drv->API.Initialize().
|
||||
*/
|
||||
static EGLBoolean
|
||||
xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
|
||||
EGLint *minor, EGLint *major)
|
||||
{
|
||||
/* visual configs */
|
||||
|
||||
init_configs(drv, dpy);
|
||||
|
||||
|
||||
drv->Initialized = EGL_TRUE;
|
||||
|
||||
/* we're supporting EGL 1.4 */
|
||||
*minor = 1;
|
||||
*major = 4;
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglTerminate(), drv->API.Terminate().
|
||||
*/
|
||||
static EGLBoolean
|
||||
xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
|
||||
{
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/** Get size of given window */
|
||||
static Status
|
||||
get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
|
||||
{
|
||||
Window root;
|
||||
Status stat;
|
||||
int xpos, ypos;
|
||||
unsigned int w, h, bw, depth;
|
||||
stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth);
|
||||
*width = w;
|
||||
*height = h;
|
||||
return stat;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
display_surface(struct pipe_winsys *pws,
|
||||
struct pipe_surface *psurf,
|
||||
struct xlib_egl_surface *xsurf)
|
||||
{
|
||||
XImage *ximage;
|
||||
void *data;
|
||||
|
||||
ximage = XCreateImage(xsurf->Dpy,
|
||||
xsurf->VisInfo.visual,
|
||||
xsurf->VisInfo.depth,
|
||||
ZPixmap, 0, /* format, offset */
|
||||
NULL, /* data */
|
||||
0, 0, /* size */
|
||||
32, /* bitmap_pad */
|
||||
0); /* bytes_per_line */
|
||||
|
||||
|
||||
assert(ximage->format);
|
||||
assert(ximage->bitmap_unit);
|
||||
|
||||
data = pws->buffer_map(pws, psurf->buffer, 0);
|
||||
|
||||
/* update XImage's fields */
|
||||
ximage->data = data;
|
||||
ximage->width = psurf->width;
|
||||
ximage->height = psurf->height;
|
||||
ximage->bytes_per_line = psurf->pitch * psurf->cpp;
|
||||
|
||||
XPutImage(xsurf->Dpy, xsurf->Win, xsurf->Gc,
|
||||
ximage, 0, 0, 0, 0, psurf->width, psurf->height);
|
||||
|
||||
ximage->data = NULL;
|
||||
XDestroyImage(ximage);
|
||||
|
||||
pws->buffer_unmap(pws, psurf->buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/** Display gallium surface in X window */
|
||||
static void
|
||||
flush_frontbuffer(struct pipe_winsys *pws,
|
||||
struct pipe_surface *psurf,
|
||||
void *context_private)
|
||||
{
|
||||
struct xlib_egl_surface *xsurf = (struct xlib_egl_surface *) context_private;
|
||||
display_surface(pws, psurf, xsurf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglCreateContext(), drv->API.CreateContext().
|
||||
*/
|
||||
static EGLContext
|
||||
xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
|
||||
EGLContext share_list, const EGLint *attrib_list)
|
||||
{
|
||||
struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
|
||||
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
|
||||
struct xlib_egl_context *ctx;
|
||||
struct st_context *share_ctx = NULL; /* XXX fix */
|
||||
__GLcontextModes visual;
|
||||
|
||||
ctx = CALLOC_STRUCT(xlib_egl_context);
|
||||
if (!ctx)
|
||||
return EGL_NO_CONTEXT;
|
||||
|
||||
/* let EGL lib init the common stuff */
|
||||
if (!_eglInitContext(drv, dpy, &ctx->Base, config, attrib_list)) {
|
||||
free(ctx);
|
||||
return EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
/* create a softpipe context */
|
||||
ctx->pipe = softpipe_create(xdrv->screen, xdrv->winsys, NULL);
|
||||
|
||||
/* Now do xlib / state tracker inits here */
|
||||
_eglConfigToContextModesRec(conf, &visual);
|
||||
ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx);
|
||||
|
||||
|
||||
return _eglGetContextHandle(&ctx->Base);
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
|
||||
{
|
||||
struct xlib_egl_context *context = lookup_context(ctx);
|
||||
if (context) {
|
||||
if (context->Base.IsBound) {
|
||||
context->Base.DeletePending = EGL_TRUE;
|
||||
}
|
||||
else {
|
||||
st_destroy_context(context->Context);
|
||||
free(context);
|
||||
}
|
||||
return EGL_TRUE;
|
||||
}
|
||||
else {
|
||||
_eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
|
||||
return EGL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
|
||||
*/
|
||||
static EGLBoolean
|
||||
xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
|
||||
EGLSurface r, EGLContext context)
|
||||
{
|
||||
if (!_eglMakeCurrent(drv, dpy, d, r, context))
|
||||
return EGL_FALSE;
|
||||
|
||||
/* XXX anything todo? */
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_format
|
||||
choose_color_format(const __GLcontextModes *visual)
|
||||
{
|
||||
if (visual->redBits == 8 &&
|
||||
visual->greenBits == 8 &&
|
||||
visual->blueBits == 8 &&
|
||||
visual->alphaBits == 8) {
|
||||
/* XXX this really also depends on the ordering of R,G,B,A */
|
||||
return PIPE_FORMAT_A8R8G8B8_UNORM;
|
||||
}
|
||||
else {
|
||||
assert(0);
|
||||
return PIPE_FORMAT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_format
|
||||
choose_depth_format(const __GLcontextModes *visual)
|
||||
{
|
||||
if (visual->depthBits > 0)
|
||||
return PIPE_FORMAT_Z24S8_UNORM;
|
||||
else
|
||||
return PIPE_FORMAT_NONE;
|
||||
}
|
||||
|
||||
|
||||
static enum pipe_format
|
||||
choose_stencil_format(const __GLcontextModes *visual)
|
||||
{
|
||||
if (visual->stencilBits > 0)
|
||||
return PIPE_FORMAT_Z24S8_UNORM;
|
||||
else
|
||||
return PIPE_FORMAT_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
|
||||
*/
|
||||
static EGLSurface
|
||||
xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
|
||||
NativeWindowType window, const EGLint *attrib_list)
|
||||
{
|
||||
struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
|
||||
_EGLDisplay *disp = _eglLookupDisplay(dpy);
|
||||
_EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
|
||||
|
||||
struct xlib_egl_surface *surf;
|
||||
__GLcontextModes visual;
|
||||
uint width, height;
|
||||
|
||||
surf = CALLOC_STRUCT(xlib_egl_surface);
|
||||
if (!surf)
|
||||
return EGL_NO_SURFACE;
|
||||
|
||||
/* Let EGL lib init the common stuff */
|
||||
if (!_eglInitSurface(drv, dpy, &surf->Base, EGL_WINDOW_BIT,
|
||||
config, attrib_list)) {
|
||||
free(surf);
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now init the Xlib and gallium stuff
|
||||
*/
|
||||
surf->Win = (Window) window; /* The X window ID */
|
||||
surf->Dpy = disp->Xdpy; /* The X display */
|
||||
surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL);
|
||||
|
||||
surf->winsys = xdrv->winsys;
|
||||
|
||||
_eglConfigToContextModesRec(conf, &visual);
|
||||
get_drawable_size(surf->Dpy, surf->Win, &width, &height);
|
||||
|
||||
/* Create GL statetracker framebuffer */
|
||||
surf->Framebuffer = st_create_framebuffer(&visual,
|
||||
choose_color_format(&visual),
|
||||
choose_depth_format(&visual),
|
||||
choose_stencil_format(&visual),
|
||||
width, height,
|
||||
(void *) surf);
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
||||
static EGLBoolean
|
||||
xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
|
||||
{
|
||||
/* error checking step: */
|
||||
if (!_eglSwapBuffers(drv, dpy, draw))
|
||||
return EGL_FALSE;
|
||||
|
||||
{
|
||||
struct xlib_egl_surface *xsurf = lookup_surface(draw);
|
||||
struct pipe_winsys *pws = xsurf->winsys;
|
||||
struct pipe_surface *psurf =
|
||||
st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT);
|
||||
|
||||
display_surface(pws, psurf, xsurf);
|
||||
}
|
||||
|
||||
return EGL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is the main entrypoint into the driver.
|
||||
* Called by libEGL to instantiate an _EGLDriver object.
|
||||
*/
|
||||
_EGLDriver *
|
||||
_eglMain(_EGLDisplay *dpy, const char *args)
|
||||
{
|
||||
struct xlib_egl_driver *xdrv;
|
||||
|
||||
_eglLog(_EGL_INFO, "Entering EGL/Xlib _eglMain(%s)", args);
|
||||
|
||||
xdrv = CALLOC_STRUCT(xlib_egl_driver);
|
||||
if (!xdrv)
|
||||
return NULL;
|
||||
|
||||
_eglInitDriverFallbacks(&xdrv->Base);
|
||||
xdrv->Base.API.Initialize = xlib_eglInitialize;
|
||||
xdrv->Base.API.Terminate = xlib_eglTerminate;
|
||||
xdrv->Base.API.CreateContext = xlib_eglCreateContext;
|
||||
xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
|
||||
xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
|
||||
xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
|
||||
xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
|
||||
|
||||
|
||||
xdrv->Base.ClientAPIs = "OpenGL"; /* "OpenGL_ES" */
|
||||
xdrv->Base.Name = "Xlib/softpipe";
|
||||
|
||||
/* create one winsys and use it for all contexts/surfaces */
|
||||
xdrv->winsys = create_sw_winsys();
|
||||
xdrv->winsys->flush_frontbuffer = flush_frontbuffer;
|
||||
|
||||
xdrv->screen = softpipe_create_screen(xdrv->winsys);
|
||||
|
||||
|
||||
return &xdrv->Base;
|
||||
}
|
||||
|
||||
244
src/gallium/winsys/egl_xlib/sw_winsys.c
Normal file
244
src/gallium/winsys/egl_xlib/sw_winsys.c
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**
|
||||
* Totally software-based winsys layer.
|
||||
* Note that the one winsys function that we can't implement here
|
||||
* is flush_frontbuffer().
|
||||
* Whoever uses this code will have to provide that.
|
||||
*
|
||||
* Authors: Brian Paul
|
||||
*/
|
||||
|
||||
|
||||
#include "pipe/p_winsys.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "pipe/p_util.h"
|
||||
#include "pipe/p_inlines.h"
|
||||
|
||||
#include "sw_winsys.h"
|
||||
|
||||
|
||||
|
||||
/** Subclass of pipe_winsys */
|
||||
struct sw_pipe_winsys
|
||||
{
|
||||
struct pipe_winsys Base;
|
||||
/* no extra fields for now */
|
||||
};
|
||||
|
||||
|
||||
/** subclass of pipe_buffer */
|
||||
struct sw_pipe_buffer
|
||||
{
|
||||
struct pipe_buffer Base;
|
||||
boolean UserBuffer; /** Is this a user-space buffer? */
|
||||
void *Data;
|
||||
void *Mapped;
|
||||
};
|
||||
|
||||
|
||||
/** cast wrapper */
|
||||
static INLINE struct sw_pipe_buffer *
|
||||
sw_pipe_buffer(struct pipe_buffer *b)
|
||||
{
|
||||
return (struct sw_pipe_buffer *) b;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *
|
||||
get_name(struct pipe_winsys *pws)
|
||||
{
|
||||
return "software";
|
||||
}
|
||||
|
||||
|
||||
/** Create new pipe_buffer and allocate storage of given size */
|
||||
static struct pipe_buffer *
|
||||
buffer_create(struct pipe_winsys *pws,
|
||||
unsigned alignment,
|
||||
unsigned usage,
|
||||
unsigned size)
|
||||
{
|
||||
struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
buffer->Base.refcount = 1;
|
||||
buffer->Base.alignment = alignment;
|
||||
buffer->Base.usage = usage;
|
||||
buffer->Base.size = size;
|
||||
|
||||
/* align to 16-byte multiple for Cell */
|
||||
buffer->Data = align_malloc(size, MAX2(alignment, 16));
|
||||
|
||||
return &buffer->Base;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create buffer which wraps user-space data.
|
||||
*/
|
||||
static struct pipe_buffer *
|
||||
user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
|
||||
{
|
||||
struct sw_pipe_buffer *buffer = CALLOC_STRUCT(sw_pipe_buffer);
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
buffer->Base.refcount = 1;
|
||||
buffer->Base.size = bytes;
|
||||
buffer->UserBuffer = TRUE;
|
||||
buffer->Data = ptr;
|
||||
|
||||
return &buffer->Base;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
buffer_map(struct pipe_winsys *pws, struct pipe_buffer *buf, unsigned flags)
|
||||
{
|
||||
struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
|
||||
buffer->Mapped = buffer->Data;
|
||||
return buffer->Mapped;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
buffer_unmap(struct pipe_winsys *pws, struct pipe_buffer *buf)
|
||||
{
|
||||
struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
|
||||
buffer->Mapped = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
buffer_destroy(struct pipe_winsys *pws, struct pipe_buffer *buf)
|
||||
{
|
||||
struct sw_pipe_buffer *buffer = sw_pipe_buffer(buf);
|
||||
|
||||
if (buffer->Data && !buffer->UserBuffer) {
|
||||
align_free(buffer->Data);
|
||||
buffer->Data = NULL;
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via winsys->surface_alloc() to create new surfaces.
|
||||
*/
|
||||
static struct pipe_surface *
|
||||
surface_alloc(struct pipe_winsys *ws)
|
||||
{
|
||||
struct pipe_surface *surf = CALLOC_STRUCT(pipe_surface);
|
||||
if (!surf)
|
||||
return NULL;
|
||||
|
||||
surf->refcount = 1;
|
||||
surf->winsys = ws;
|
||||
|
||||
return surf;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
surface_release(struct pipe_winsys *winsys, struct pipe_surface **s)
|
||||
{
|
||||
struct pipe_surface *surf = *s;
|
||||
assert(!surf->texture);
|
||||
surf->refcount--;
|
||||
if (surf->refcount == 0) {
|
||||
if (surf->buffer)
|
||||
pipe_buffer_reference(winsys, &surf->buffer, NULL);
|
||||
free(surf);
|
||||
}
|
||||
*s = NULL;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fence_reference(struct pipe_winsys *sws, struct pipe_fence_handle **ptr,
|
||||
struct pipe_fence_handle *fence)
|
||||
{
|
||||
/* no-op */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fence_signalled(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
/* no-op */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
fence_finish(struct pipe_winsys *sws, struct pipe_fence_handle *fence,
|
||||
unsigned flag)
|
||||
{
|
||||
/* no-op */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create/return a new pipe_winsys object.
|
||||
*/
|
||||
struct pipe_winsys *
|
||||
create_sw_winsys(void)
|
||||
{
|
||||
struct sw_pipe_winsys *ws = CALLOC_STRUCT(sw_pipe_winsys);
|
||||
if (!ws)
|
||||
return NULL;
|
||||
|
||||
/* Fill in this struct with callbacks that pipe will need to
|
||||
* communicate with the window system, buffer manager, etc.
|
||||
*/
|
||||
ws->Base.buffer_create = buffer_create;
|
||||
ws->Base.user_buffer_create = user_buffer_create;
|
||||
ws->Base.buffer_map = buffer_map;
|
||||
ws->Base.buffer_unmap = buffer_unmap;
|
||||
ws->Base.buffer_destroy = buffer_destroy;
|
||||
|
||||
ws->Base.surface_alloc = surface_alloc;
|
||||
ws->Base.surface_alloc_storage = NULL; /* unused */
|
||||
ws->Base.surface_release = surface_release;
|
||||
|
||||
ws->Base.fence_reference = fence_reference;
|
||||
ws->Base.fence_signalled = fence_signalled;
|
||||
ws->Base.fence_finish = fence_finish;
|
||||
|
||||
ws->Base.flush_frontbuffer = NULL; /* not implemented here! */
|
||||
|
||||
ws->Base.get_name = get_name;
|
||||
|
||||
return &ws->Base;
|
||||
}
|
||||
40
src/gallium/winsys/egl_xlib/sw_winsys.h
Normal file
40
src/gallium/winsys/egl_xlib/sw_winsys.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/**************************************************************************
|
||||
*
|
||||
* Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
|
||||
* 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 NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS 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.
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
|
||||
#ifndef SW_WINSYS_H
|
||||
#define SW_WINSYS_H
|
||||
|
||||
|
||||
struct pipe_winsys;
|
||||
|
||||
|
||||
extern struct pipe_winsys *
|
||||
create_sw_winsys(void);
|
||||
|
||||
|
||||
#endif /* SW_WINSYS_H */
|
||||
Loading…
Add table
Reference in a new issue