st/egl: Move module loading code to targets.
Several changes are made. libegl.a no longer defines _eglMain. It defines functions to create and destroy a _EGLDriver instead. The creation function is called by the targets. It takes an egl_g3d_loader as its argument. The loader is defined by the targets and is in charge of creating st_api and pipe_screen. This allows us to move the module loading code to targets. Lastly, the modules are now loaded as the respective contexts are created.
This commit is contained in:
@@ -5,14 +5,12 @@ common_INCLUDES = \
|
||||
-I. \
|
||||
-I$(TOP)/src/gallium/include \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/src/egl/main \
|
||||
-I$(TOP)/include
|
||||
|
||||
common_SOURCES = $(wildcard common/*.c)
|
||||
common_OBJECTS = $(common_SOURCES:.c=.o)
|
||||
|
||||
|
||||
x11_INCLUDES = \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
-I$(TOP)/src/glx \
|
||||
@@ -31,7 +29,7 @@ kms_SOURCES = $(wildcard kms/*.c)
|
||||
kms_OBJECTS = $(kms_SOURCES:.c=.o)
|
||||
|
||||
|
||||
fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw -I$(TOP)/src/gallium/drivers
|
||||
fbdev_INCLUDES = -I$(TOP)/src/gallium/winsys/sw
|
||||
fbdev_SOURCES = $(wildcard fbdev/*.c)
|
||||
fbdev_OBJECTS = $(fbdev_SOURCES:.c=.o)
|
||||
|
||||
@@ -40,7 +38,7 @@ ALL_INCLUDES = $(common_INCLUDES) $(x11_INCLUDES) $(kms_INCLUDES) $(fbdev_INCLUD
|
||||
ALL_SOURCES = $(common_SOURCES) $(x11_SOURCES) $(kms_SOURCES) $(fbdev_SOURCES)
|
||||
|
||||
EGL_OBJECTS = $(common_OBJECTS)
|
||||
EGL_CPPFLAGS = $(common_INCLUDES) -DST_MODULE_PREFIX=\"st_\"
|
||||
EGL_CPPFLAGS = $(common_INCLUDES)
|
||||
|
||||
# add backends
|
||||
ifneq ($(findstring x11, $(EGL_PLATFORMS)),)
|
||||
|
||||
@@ -35,33 +35,9 @@
|
||||
#include "egl_g3d.h"
|
||||
#include "egl_g3d_api.h"
|
||||
#include "egl_g3d_st.h"
|
||||
#include "egl_g3d_loader.h"
|
||||
#include "native.h"
|
||||
|
||||
/**
|
||||
* Initialize the state trackers.
|
||||
*/
|
||||
static void
|
||||
egl_g3d_init_st(_EGLDriver *drv)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
EGLint i;
|
||||
|
||||
/* already initialized */
|
||||
if (gdrv->api_mask)
|
||||
return;
|
||||
|
||||
egl_g3d_init_st_apis(gdrv->stapis);
|
||||
for (i = 0; i < ST_API_COUNT; i++) {
|
||||
if (gdrv->stapis[i])
|
||||
gdrv->api_mask |= egl_g3d_st_api_bit(i);
|
||||
}
|
||||
|
||||
if (gdrv->api_mask)
|
||||
_eglLog(_EGL_DEBUG, "Driver API mask: 0x%x", gdrv->api_mask);
|
||||
else
|
||||
_eglLog(_EGL_WARNING, "No supported client API");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native platform.
|
||||
*/
|
||||
@@ -323,7 +299,6 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
|
||||
_EGLConfig *conf, const struct native_config *nconf,
|
||||
enum pipe_format depth_stencil_format)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
struct egl_g3d_config *gconf = egl_g3d_config(conf);
|
||||
EGLint buffer_mask, api_mask;
|
||||
EGLBoolean valid;
|
||||
@@ -347,7 +322,7 @@ egl_g3d_init_config(_EGLDriver *drv, _EGLDisplay *dpy,
|
||||
gconf->stvis.render_buffer = (buffer_mask & ST_ATTACHMENT_BACK_LEFT_MASK) ?
|
||||
ST_ATTACHMENT_BACK_LEFT : ST_ATTACHMENT_FRONT_LEFT;
|
||||
|
||||
api_mask = gdrv->api_mask;;
|
||||
api_mask = dpy->ClientAPIsMask;
|
||||
/* this is required by EGL, not by OpenGL ES */
|
||||
if (nconf->window_bit &&
|
||||
gconf->stvis.render_buffer != ST_ATTACHMENT_BACK_LEFT)
|
||||
@@ -472,8 +447,26 @@ egl_g3d_invalid_surface(struct native_display *ndpy,
|
||||
gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi);
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
egl_g3d_new_drm_screen(struct native_display *ndpy, const char *name, int fd)
|
||||
{
|
||||
_EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
|
||||
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
|
||||
return gdpy->loader->create_drm_screen(name, fd);
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
egl_g3d_new_sw_screen(struct native_display *ndpy, struct sw_winsys *ws)
|
||||
{
|
||||
_EGLDisplay *dpy = (_EGLDisplay *) ndpy->user_data;
|
||||
struct egl_g3d_display *gdpy = egl_g3d_display(dpy);
|
||||
return gdpy->loader->create_sw_screen(ws);
|
||||
}
|
||||
|
||||
static struct native_event_handler egl_g3d_native_event_handler = {
|
||||
egl_g3d_invalid_surface
|
||||
egl_g3d_invalid_surface,
|
||||
egl_g3d_new_drm_screen,
|
||||
egl_g3d_new_sw_screen
|
||||
};
|
||||
|
||||
static EGLBoolean
|
||||
@@ -529,20 +522,25 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy,
|
||||
_eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
goto fail;
|
||||
}
|
||||
gdpy->loader = gdrv->loader;
|
||||
dpy->DriverData = gdpy;
|
||||
|
||||
_eglLog(_EGL_INFO, "use %s for display %p", nplat->name, dpy->PlatformDisplay);
|
||||
gdpy->native = nplat->create_display(dpy->PlatformDisplay,
|
||||
&egl_g3d_native_event_handler);
|
||||
&egl_g3d_native_event_handler, (void *) dpy);
|
||||
if (!gdpy->native) {
|
||||
_eglError(EGL_NOT_INITIALIZED, "eglInitialize(no usable display)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
gdpy->native->user_data = (void *) dpy;
|
||||
|
||||
egl_g3d_init_st(&gdrv->base);
|
||||
dpy->ClientAPIsMask = gdrv->api_mask;
|
||||
if (gdpy->loader->api_mask & (1 << ST_API_OPENGL))
|
||||
dpy->ClientAPIsMask |= EGL_OPENGL_BIT;
|
||||
if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES1))
|
||||
dpy->ClientAPIsMask |= EGL_OPENGL_ES_BIT;
|
||||
if (gdpy->loader->api_mask & (1 << ST_API_OPENGL_ES2))
|
||||
dpy->ClientAPIsMask |= EGL_OPENGL_ES2_BIT;
|
||||
if (gdpy->loader->api_mask & (1 << ST_API_OPENVG))
|
||||
dpy->ClientAPIsMask |= EGL_OPENVG_BIT;
|
||||
|
||||
gdpy->smapi = egl_g3d_create_st_manager(dpy);
|
||||
if (!gdpy->smapi) {
|
||||
@@ -583,22 +581,15 @@ static _EGLProc
|
||||
egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
_EGLProc proc;
|
||||
EGLint i;
|
||||
struct st_api *stapi = NULL;
|
||||
|
||||
/* in case this is called before a display is initialized */
|
||||
egl_g3d_init_st(&gdrv->base);
|
||||
if (procname && procname[0] == 'v' && procname[1] == 'g')
|
||||
stapi = gdrv->loader->get_st_api(ST_API_OPENVG);
|
||||
else if (procname && procname[0] == 'g' && procname[1] == 'l')
|
||||
stapi = gdrv->loader->guess_gl_api();
|
||||
|
||||
for (i = 0; i < ST_API_COUNT; i++) {
|
||||
struct st_api *stapi = gdrv->stapis[i];
|
||||
if (stapi) {
|
||||
proc = (_EGLProc) stapi->get_proc_address(stapi, procname);
|
||||
if (proc)
|
||||
return proc;
|
||||
}
|
||||
}
|
||||
|
||||
return (_EGLProc) NULL;
|
||||
return (_EGLProc) ((stapi) ?
|
||||
stapi->get_proc_address(stapi, procname) : NULL);
|
||||
}
|
||||
|
||||
static EGLint
|
||||
@@ -628,18 +619,8 @@ egl_g3d_probe(_EGLDriver *drv, _EGLDisplay *dpy)
|
||||
return score;
|
||||
}
|
||||
|
||||
static void
|
||||
egl_g3d_unload(_EGLDriver *drv)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
|
||||
egl_g3d_destroy_st_apis();
|
||||
egl_g3d_destroy_probe(drv, NULL);
|
||||
FREE(gdrv);
|
||||
}
|
||||
|
||||
_EGLDriver *
|
||||
_eglMain(const char *args)
|
||||
egl_g3d_create_driver(const struct egl_g3d_loader *loader)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv;
|
||||
|
||||
@@ -647,17 +628,28 @@ _eglMain(const char *args)
|
||||
if (!gdrv)
|
||||
return NULL;
|
||||
|
||||
gdrv->loader = loader;
|
||||
|
||||
egl_g3d_init_driver_api(&gdrv->base);
|
||||
gdrv->base.API.Initialize = egl_g3d_initialize;
|
||||
gdrv->base.API.Terminate = egl_g3d_terminate;
|
||||
gdrv->base.API.GetProcAddress = egl_g3d_get_proc_address;
|
||||
|
||||
gdrv->base.Name = "Gallium";
|
||||
gdrv->base.Probe = egl_g3d_probe;
|
||||
gdrv->base.Unload = egl_g3d_unload;
|
||||
|
||||
/* the key is " EGL G3D" */
|
||||
gdrv->probe_key = 0x0E61063D;
|
||||
|
||||
/* to be filled by the caller */
|
||||
gdrv->base.Name = NULL;
|
||||
gdrv->base.Unload = NULL;
|
||||
|
||||
return &gdrv->base;
|
||||
}
|
||||
|
||||
void
|
||||
egl_g3d_destroy_driver(_EGLDriver *drv)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
FREE(gdrv);
|
||||
}
|
||||
|
||||
@@ -41,12 +41,11 @@
|
||||
|
||||
#include "native.h"
|
||||
#include "egl_g3d_st.h"
|
||||
#include "egl_g3d_loader.h"
|
||||
|
||||
struct egl_g3d_driver {
|
||||
_EGLDriver base;
|
||||
struct st_api *stapis[ST_API_COUNT];
|
||||
EGLint api_mask;
|
||||
|
||||
const struct egl_g3d_loader *loader;
|
||||
const struct native_platform *platforms[_EGL_NUM_PLATFORMS];
|
||||
EGLint probe_key;
|
||||
};
|
||||
@@ -54,6 +53,7 @@ struct egl_g3d_driver {
|
||||
struct egl_g3d_display {
|
||||
struct native_display *native;
|
||||
|
||||
const struct egl_g3d_loader *loader;
|
||||
struct st_manager *smapi;
|
||||
struct pipe_context *pipe;
|
||||
};
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "egl_g3d_api.h"
|
||||
#include "egl_g3d_image.h"
|
||||
#include "egl_g3d_st.h"
|
||||
#include "egl_g3d_loader.h"
|
||||
#include "native.h"
|
||||
|
||||
/**
|
||||
@@ -44,7 +45,6 @@ static struct st_api *
|
||||
egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
|
||||
{
|
||||
struct egl_g3d_driver *gdrv = egl_g3d_driver(drv);
|
||||
struct st_api *stapi;
|
||||
EGLint idx = -1;
|
||||
|
||||
switch (ctx->ClientAPI) {
|
||||
@@ -73,8 +73,7 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx)
|
||||
break;
|
||||
}
|
||||
|
||||
stapi = (idx >= 0) ? gdrv->stapis[idx] : NULL;
|
||||
return stapi;
|
||||
return (idx >= 0) ? gdrv->loader->get_st_api(idx) : NULL;
|
||||
}
|
||||
|
||||
static _EGLContext *
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* 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, sublicense,
|
||||
* 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 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.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#ifndef _EGL_G3D_LOADER_H_
|
||||
#define _EGL_G3D_LOADER_H_
|
||||
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "state_tracker/st_api.h"
|
||||
#include "egltypedefs.h"
|
||||
|
||||
struct pipe_screen;
|
||||
struct sw_winsys;
|
||||
|
||||
struct egl_g3d_loader {
|
||||
uint api_mask;
|
||||
struct st_api *(*get_st_api)(enum st_api_type api);
|
||||
struct st_api *(*guess_gl_api)(void);
|
||||
|
||||
struct pipe_screen *(*create_drm_screen)(const char *name, int fd);
|
||||
struct pipe_screen *(*create_sw_screen)(struct sw_winsys *ws);
|
||||
};
|
||||
|
||||
_EGLDriver *
|
||||
egl_g3d_create_driver(const struct egl_g3d_loader *loader);
|
||||
|
||||
void
|
||||
egl_g3d_destroy_driver(_EGLDriver *drv);
|
||||
|
||||
#endif /* _EGL_G3D_LOADER_H_ */
|
||||
@@ -49,173 +49,6 @@ egl_g3d_st_manager(struct st_manager *smapi)
|
||||
return (struct egl_g3d_st_manager *) smapi;
|
||||
}
|
||||
|
||||
static struct egl_g3d_st_module {
|
||||
const char *filename;
|
||||
struct util_dl_library *lib;
|
||||
struct st_api *stapi;
|
||||
} egl_g3d_st_modules[ST_API_COUNT];
|
||||
|
||||
static EGLBoolean
|
||||
egl_g3d_search_path_callback(const char *dir, size_t len, void *callback_data)
|
||||
{
|
||||
struct egl_g3d_st_module *stmod =
|
||||
(struct egl_g3d_st_module *) callback_data;
|
||||
char path[1024];
|
||||
int ret;
|
||||
|
||||
if (!len) {
|
||||
stmod->lib = util_dl_open(stmod->filename);
|
||||
return !(stmod->lib);
|
||||
}
|
||||
|
||||
ret = util_snprintf(path, sizeof(path),
|
||||
"%.*s/%s", len, dir, stmod->filename);
|
||||
if (ret > 0 && ret < sizeof(path))
|
||||
stmod->lib = util_dl_open(path);
|
||||
|
||||
return !(stmod->lib);
|
||||
}
|
||||
|
||||
static boolean
|
||||
egl_g3d_load_st_module(struct egl_g3d_st_module *stmod,
|
||||
const char *filename, const char *procname)
|
||||
{
|
||||
struct st_api *(*create_api)(void);
|
||||
|
||||
stmod->filename = filename;
|
||||
if (stmod->filename)
|
||||
_eglSearchPathForEach(egl_g3d_search_path_callback, (void *) stmod);
|
||||
else
|
||||
stmod->lib = util_dl_open(NULL);
|
||||
|
||||
if (stmod->lib) {
|
||||
create_api = (struct st_api *(*)(void))
|
||||
util_dl_get_proc_address(stmod->lib, procname);
|
||||
if (create_api)
|
||||
stmod->stapi = create_api();
|
||||
|
||||
if (!stmod->stapi) {
|
||||
util_dl_close(stmod->lib);
|
||||
stmod->lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (stmod->stapi) {
|
||||
return TRUE;
|
||||
}
|
||||
else {
|
||||
stmod->filename = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PIPE_OS_WINDOWS
|
||||
#define ST_MODULE_SUFFIX ".dll"
|
||||
#else
|
||||
#define ST_MODULE_SUFFIX ".so"
|
||||
#endif
|
||||
|
||||
void
|
||||
egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT])
|
||||
{
|
||||
const char *skip_checks[ST_API_COUNT], *symbols[ST_API_COUNT];
|
||||
const char *filenames[ST_API_COUNT][4];
|
||||
struct util_dl_library *self;
|
||||
int num_needed = 0, api;
|
||||
|
||||
self = util_dl_open(NULL);
|
||||
|
||||
/* collect the necessary data for loading modules */
|
||||
for (api = 0; api < ST_API_COUNT; api++) {
|
||||
int count = 0;
|
||||
|
||||
switch (api) {
|
||||
case ST_API_OPENGL:
|
||||
skip_checks[api] = "glColor4d";
|
||||
symbols[api] = ST_CREATE_OPENGL_SYMBOL;
|
||||
filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX;
|
||||
break;
|
||||
case ST_API_OPENGL_ES1:
|
||||
skip_checks[api] = "glColor4x";
|
||||
symbols[api] = ST_CREATE_OPENGL_ES1_SYMBOL;
|
||||
filenames[api][count++] = ST_MODULE_PREFIX "GLESv1_CM" ST_MODULE_SUFFIX;
|
||||
filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX;
|
||||
break;
|
||||
case ST_API_OPENGL_ES2:
|
||||
skip_checks[api] = "glShaderBinary";
|
||||
symbols[api] = ST_CREATE_OPENGL_ES2_SYMBOL;
|
||||
filenames[api][count++] = ST_MODULE_PREFIX "GLESv2" ST_MODULE_SUFFIX;
|
||||
filenames[api][count++] = ST_MODULE_PREFIX "GL" ST_MODULE_SUFFIX;
|
||||
break;
|
||||
case ST_API_OPENVG:
|
||||
skip_checks[api] = "vgClear";
|
||||
symbols[api] = ST_CREATE_OPENVG_SYMBOL;
|
||||
filenames[api][count++]= ST_MODULE_PREFIX "OpenVG" ST_MODULE_SUFFIX;
|
||||
break;
|
||||
default:
|
||||
assert(!"Unknown API Type\n");
|
||||
skip_checks[api] = NULL;
|
||||
symbols[api] = NULL;
|
||||
break;
|
||||
}
|
||||
filenames[api][count++]= NULL;
|
||||
assert(count < Elements(filenames[api]));
|
||||
|
||||
/* heuristicically decide if the module is needed */
|
||||
if (!self || !skip_checks[api] ||
|
||||
util_dl_get_proc_address(self, skip_checks[api])) {
|
||||
/* unset so the module is not skipped */
|
||||
skip_checks[api] = NULL;
|
||||
num_needed++;
|
||||
}
|
||||
}
|
||||
/* mark all moudles needed if we wrongly decided that none is needed */
|
||||
if (!num_needed)
|
||||
memset(skip_checks, 0, sizeof(skip_checks));
|
||||
|
||||
if (self)
|
||||
util_dl_close(self);
|
||||
|
||||
for (api = 0; api < ST_API_COUNT; api++) {
|
||||
struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api];
|
||||
const char **p;
|
||||
|
||||
/* skip the module */
|
||||
if (skip_checks[api])
|
||||
continue;
|
||||
|
||||
/* try all filenames, including NULL */
|
||||
for (p = filenames[api]; *p; p++) {
|
||||
if (egl_g3d_load_st_module(stmod, *p, symbols[api]))
|
||||
break;
|
||||
}
|
||||
if (!stmod->stapi)
|
||||
egl_g3d_load_st_module(stmod, NULL, symbols[api]);
|
||||
|
||||
stapis[api] = stmod->stapi;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
egl_g3d_destroy_st_apis(void)
|
||||
{
|
||||
int api;
|
||||
|
||||
for (api = 0; api < ST_API_COUNT; api++) {
|
||||
struct egl_g3d_st_module *stmod = &egl_g3d_st_modules[api];
|
||||
|
||||
if (stmod->stapi) {
|
||||
stmod->stapi->destroy(stmod->stapi);
|
||||
stmod->stapi = NULL;
|
||||
}
|
||||
if (stmod->lib) {
|
||||
util_dl_close(stmod->lib);
|
||||
stmod->lib = NULL;
|
||||
}
|
||||
stmod->filename = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static boolean
|
||||
egl_g3d_st_manager_get_egl_image(struct st_manager *smapi,
|
||||
struct st_context_iface *stctx,
|
||||
|
||||
@@ -33,12 +33,6 @@
|
||||
#include "state_tracker/st_api.h"
|
||||
#include "egltypedefs.h"
|
||||
|
||||
void
|
||||
egl_g3d_init_st_apis(struct st_api *stapis[ST_API_COUNT]);
|
||||
|
||||
void
|
||||
egl_g3d_destroy_st_apis(void);
|
||||
|
||||
struct st_manager *
|
||||
egl_g3d_create_st_manager(_EGLDisplay *dpy);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
|
||||
#include "native_probe.h"
|
||||
#include "native_modeset.h"
|
||||
@@ -196,6 +197,11 @@ struct native_event_handler {
|
||||
void (*invalid_surface)(struct native_display *ndpy,
|
||||
struct native_surface *nsurf,
|
||||
unsigned int seq_num);
|
||||
|
||||
struct pipe_screen *(*new_drm_screen)(struct native_display *ndpy,
|
||||
const char *name, int fd);
|
||||
struct pipe_screen *(*new_sw_screen)(struct native_display *ndpy,
|
||||
struct sw_winsys *ws);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -225,7 +231,8 @@ struct native_platform {
|
||||
enum native_probe_result (*get_probe_result)(struct native_probe *nprobe);
|
||||
|
||||
struct native_display *(*create_display)(void *dpy,
|
||||
struct native_event_handler *handler);
|
||||
struct native_event_handler *handler,
|
||||
void *user_data);
|
||||
};
|
||||
|
||||
const struct native_platform *
|
||||
|
||||
@@ -31,9 +31,6 @@
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "softpipe/sp_public.h"
|
||||
#include "llvmpipe/lp_public.h"
|
||||
#include "target-helpers/wrap_screen.h"
|
||||
|
||||
#include "native_helper.h"
|
||||
|
||||
@@ -236,18 +233,3 @@ resource_surface_present(struct resource_surface *rsurf,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct pipe_screen *
|
||||
native_create_sw_screen(struct sw_winsys *ws)
|
||||
{
|
||||
struct pipe_screen *screen = NULL;
|
||||
|
||||
#if defined(GALLIUM_LLVMPIPE)
|
||||
if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
|
||||
screen = llvmpipe_create_screen(ws);
|
||||
#endif
|
||||
if (!screen)
|
||||
screen = softpipe_create_screen(ws);
|
||||
|
||||
return (screen) ? gallium_wrap_screen(screen) : NULL;
|
||||
}
|
||||
|
||||
@@ -69,6 +69,3 @@ boolean
|
||||
resource_surface_present(struct resource_surface *rsurf,
|
||||
enum native_attachment which,
|
||||
void *winsys_drawable_handle);
|
||||
|
||||
struct pipe_screen *
|
||||
native_create_sw_screen(struct sw_winsys *ws);
|
||||
|
||||
@@ -386,8 +386,10 @@ fbdev_display_init(struct native_display *ndpy)
|
||||
return FALSE;
|
||||
|
||||
ws = fbdev_create_sw_winsys(fbdpy->fd, fbdpy->config.color_format);
|
||||
if (ws)
|
||||
fbdpy->base.screen = native_create_sw_screen(ws);
|
||||
if (ws) {
|
||||
fbdpy->base.screen =
|
||||
fbdpy->event_handler->new_sw_screen(&fbdpy->base, ws);
|
||||
}
|
||||
|
||||
if (fbdpy->base.screen) {
|
||||
if (!fbdpy->base.screen->is_format_supported(fbdpy->base.screen,
|
||||
@@ -402,7 +404,8 @@ fbdev_display_init(struct native_display *ndpy)
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
fbdev_display_create(int fd, struct native_event_handler *event_handler)
|
||||
fbdev_display_create(int fd, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct fbdev_display *fbdpy;
|
||||
|
||||
@@ -412,6 +415,7 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler)
|
||||
|
||||
fbdpy->fd = fd;
|
||||
fbdpy->event_handler = event_handler;
|
||||
fbdpy->base.user_data = user_data;
|
||||
|
||||
if (!fbdev_display_init(&fbdpy->base)) {
|
||||
FREE(fbdpy);
|
||||
@@ -428,7 +432,8 @@ fbdev_display_create(int fd, struct native_event_handler *event_handler)
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler)
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct native_display *ndpy;
|
||||
int fd;
|
||||
@@ -443,7 +448,7 @@ native_create_display(void *dpy, struct native_event_handler *event_handler)
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
ndpy = fbdev_display_create(fd, event_handler);
|
||||
ndpy = fbdev_display_create(fd, event_handler, user_data);
|
||||
if (!ndpy)
|
||||
close(fd);
|
||||
|
||||
|
||||
@@ -343,10 +343,11 @@ gdi_display_destroy(struct native_display *ndpy)
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
gdi_create_display(HDC hDC, struct pipe_screen *screen,
|
||||
struct native_event_handler *event_handler)
|
||||
gdi_create_display(HDC hDC, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct gdi_display *gdpy;
|
||||
struct sw_winsys *winsys;
|
||||
|
||||
gdpy = CALLOC_STRUCT(gdi_display);
|
||||
if (!gdpy)
|
||||
@@ -354,8 +355,21 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen,
|
||||
|
||||
gdpy->hDC = hDC;
|
||||
gdpy->event_handler = event_handler;
|
||||
gdpy->base.user_data = user_data;
|
||||
|
||||
gdpy->base.screen = screen;
|
||||
winsys = gdi_create_sw_winsys();
|
||||
if (!winsys) {
|
||||
FREE(gdpy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdpy->base.screen = gdpy->event_handler->create_sw_screen(winsys);
|
||||
if (!gdpy->base.screen) {
|
||||
if (winsys->destroy)
|
||||
winsys->destroy(winsys);
|
||||
FREE(gdpy);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gdpy->base.destroy = gdi_display_destroy;
|
||||
gdpy->base.get_param = gdi_display_get_param;
|
||||
@@ -367,23 +381,10 @@ gdi_create_display(HDC hDC, struct pipe_screen *screen,
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler)
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct sw_winsys *winsys;
|
||||
struct pipe_screen *screen;
|
||||
|
||||
winsys = gdi_create_sw_winsys();
|
||||
if (!winsys)
|
||||
return NULL;
|
||||
|
||||
screen = native_create_sw_screen(winsys);
|
||||
if (!screen) {
|
||||
if (winsys->destroy)
|
||||
winsys->destroy(winsys);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return gdi_create_display((HDC) dpy, screen, event_handler);
|
||||
return gdi_create_display((HDC) dpy, event_handler, user_data);
|
||||
}
|
||||
|
||||
static const struct native_platform gdi_platform = {
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "pipe/p_screen.h"
|
||||
#include "pipe/p_context.h"
|
||||
#include "util/u_debug.h"
|
||||
@@ -33,7 +37,6 @@
|
||||
#include "egllog.h"
|
||||
|
||||
#include "native_kms.h"
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
static boolean
|
||||
kms_surface_validate(struct native_surface *nsurf, uint attachment_mask,
|
||||
@@ -656,7 +659,7 @@ kms_display_destroy(struct native_display *ndpy)
|
||||
kdpy->base.screen->destroy(kdpy->base.screen);
|
||||
|
||||
if (kdpy->fd >= 0)
|
||||
drmClose(kdpy->fd);
|
||||
close(kdpy->fd);
|
||||
|
||||
FREE(kdpy);
|
||||
}
|
||||
@@ -668,50 +671,23 @@ static boolean
|
||||
kms_display_init_screen(struct native_display *ndpy)
|
||||
{
|
||||
struct kms_display *kdpy = kms_display(ndpy);
|
||||
int fd;
|
||||
drmVersionPtr version;
|
||||
|
||||
fd = kdpy->fd;
|
||||
if (fd >= 0) {
|
||||
drmVersionPtr version = drmGetVersion(fd);
|
||||
if (!version || strcmp(version->name, driver_descriptor.driver_name)) {
|
||||
if (version) {
|
||||
_eglLog(_EGL_WARNING, "unknown driver name %s", version->name);
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
else {
|
||||
_eglLog(_EGL_WARNING, "invalid fd %d", fd);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
drmFreeVersion(version);
|
||||
}
|
||||
else {
|
||||
fd = drmOpen(driver_descriptor.driver_name, NULL);
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
_eglLog(_EGL_WARNING, "failed to open DRM device");
|
||||
version = drmGetVersion(kdpy->fd);
|
||||
if (!version) {
|
||||
_eglLog(_EGL_WARNING, "invalid fd %d", kdpy->fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (drmSetMaster(fd)) {
|
||||
_eglLog(_EGL_WARNING, "failed to become DRM master");
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
kdpy->base.screen = kdpy->event_handler->new_drm_screen(&kdpy->base,
|
||||
version->name, kdpy->fd);;
|
||||
drmFreeVersion(version);
|
||||
|
||||
kdpy->base.screen = driver_descriptor.create_screen(fd);
|
||||
if (!kdpy->base.screen) {
|
||||
_eglLog(_EGL_WARNING, "failed to create DRM screen");
|
||||
drmClose(fd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
kdpy->fd = fd;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -723,7 +699,8 @@ static struct native_display_modeset kms_display_modeset = {
|
||||
};
|
||||
|
||||
static struct native_display *
|
||||
kms_create_display(int fd, struct native_event_handler *event_handler)
|
||||
kms_create_display(int fd, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct kms_display *kdpy;
|
||||
|
||||
@@ -731,8 +708,10 @@ kms_create_display(int fd, struct native_event_handler *event_handler)
|
||||
if (!kdpy)
|
||||
return NULL;
|
||||
|
||||
kdpy->event_handler = event_handler;
|
||||
kdpy->fd = fd;
|
||||
kdpy->event_handler = event_handler;
|
||||
kdpy->base.user_data = user_data;
|
||||
|
||||
if (!kms_display_init_screen(&kdpy->base)) {
|
||||
kms_display_destroy(&kdpy->base);
|
||||
return NULL;
|
||||
@@ -769,39 +748,32 @@ kms_create_display(int fd, struct native_event_handler *event_handler)
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler)
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct native_display *ndpy;
|
||||
int fd;
|
||||
|
||||
/* well, this makes fd 0 being ignored */
|
||||
fd = (dpy) ? (int) pointer_to_intptr(dpy) : -1;
|
||||
ndpy = kms_create_display(fd, event_handler);
|
||||
if (dpy) {
|
||||
fd = dup((int) pointer_to_intptr(dpy));
|
||||
}
|
||||
else {
|
||||
fd = open("/dev/dri/card0", O_RDWR);
|
||||
}
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
return ndpy;
|
||||
return kms_create_display(fd, event_handler, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
kms_init_platform(struct native_platform *nplat)
|
||||
{
|
||||
static char kms_name[32];
|
||||
|
||||
if (nplat->name)
|
||||
return;
|
||||
|
||||
util_snprintf(kms_name, sizeof(kms_name), "KMS/%s", driver_descriptor.name);
|
||||
|
||||
nplat->name = kms_name;
|
||||
nplat->create_probe = NULL;
|
||||
nplat->get_probe_result = NULL;
|
||||
nplat->create_display = native_create_display;
|
||||
}
|
||||
|
||||
static struct native_platform kms_platform;
|
||||
static const struct native_platform kms_platform = {
|
||||
"KMS", /* name */
|
||||
NULL, /* create_probe */
|
||||
NULL, /* get_probe_result */
|
||||
native_create_display
|
||||
};
|
||||
|
||||
const struct native_platform *
|
||||
native_get_kms_platform(void)
|
||||
{
|
||||
kms_init_platform(&kms_platform);
|
||||
return &kms_platform;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "util/u_format.h"
|
||||
#include "pipe/p_state.h"
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
#include "common/native.h"
|
||||
#include "common/native_helper.h"
|
||||
|
||||
@@ -692,7 +692,6 @@ static boolean
|
||||
dri2_display_init_screen(struct native_display *ndpy)
|
||||
{
|
||||
struct dri2_display *dri2dpy = dri2_display(ndpy);
|
||||
const char *driver = driver_descriptor.name;
|
||||
int fd;
|
||||
|
||||
if (!x11_screen_support(dri2dpy->xscr, X11_SCREEN_EXTENSION_DRI2) ||
|
||||
@@ -703,19 +702,15 @@ dri2_display_init_screen(struct native_display *ndpy)
|
||||
|
||||
dri2dpy->dri_driver = x11_screen_probe_dri2(dri2dpy->xscr,
|
||||
&dri2dpy->dri_major, &dri2dpy->dri_minor);
|
||||
if (!dri2dpy->dri_driver || !driver ||
|
||||
strcmp(dri2dpy->dri_driver, driver) != 0) {
|
||||
_eglLog(_EGL_WARNING, "Driver mismatch: %s != %s",
|
||||
dri2dpy->dri_driver, driver);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fd = x11_screen_enable_dri2(dri2dpy->xscr,
|
||||
dri2_display_invalidate_buffers, &dri2dpy->base);
|
||||
if (fd < 0)
|
||||
return FALSE;
|
||||
|
||||
dri2dpy->base.screen = driver_descriptor.create_screen(fd);
|
||||
dri2dpy->base.screen =
|
||||
dri2dpy->event_handler->new_drm_screen(&dri2dpy->base,
|
||||
dri2dpy->dri_driver, fd);
|
||||
if (!dri2dpy->base.screen) {
|
||||
_eglLog(_EGL_WARNING, "failed to create DRM screen");
|
||||
return FALSE;
|
||||
@@ -739,7 +734,8 @@ dri2_display_hash_table_compare(void *key1, void *key2)
|
||||
|
||||
struct native_display *
|
||||
x11_create_dri2_display(Display *dpy,
|
||||
struct native_event_handler *event_handler)
|
||||
struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct dri2_display *dri2dpy;
|
||||
|
||||
@@ -748,6 +744,7 @@ x11_create_dri2_display(Display *dpy,
|
||||
return NULL;
|
||||
|
||||
dri2dpy->event_handler = event_handler;
|
||||
dri2dpy->base.user_data = user_data;
|
||||
|
||||
dri2dpy->dpy = dpy;
|
||||
if (!dri2dpy->dpy) {
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_string.h"
|
||||
@@ -107,50 +106,38 @@ x11_get_probe_result(struct native_probe *nprobe)
|
||||
}
|
||||
|
||||
static struct native_display *
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler)
|
||||
native_create_display(void *dpy, struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct native_display *ndpy = NULL;
|
||||
boolean force_sw;
|
||||
|
||||
force_sw = debug_get_bool_option("EGL_SOFTWARE", FALSE);
|
||||
if (!driver_descriptor.create_screen)
|
||||
force_sw = TRUE;
|
||||
|
||||
if (!force_sw) {
|
||||
ndpy = x11_create_dri2_display((Display *) dpy, event_handler);
|
||||
ndpy = x11_create_dri2_display((Display *) dpy,
|
||||
event_handler, user_data);
|
||||
}
|
||||
|
||||
if (!ndpy) {
|
||||
EGLint level = (force_sw) ? _EGL_INFO : _EGL_WARNING;
|
||||
|
||||
_eglLog(level, "use software fallback");
|
||||
ndpy = x11_create_ximage_display((Display *) dpy, event_handler);
|
||||
ndpy = x11_create_ximage_display((Display *) dpy,
|
||||
event_handler, user_data);
|
||||
}
|
||||
|
||||
return ndpy;
|
||||
}
|
||||
|
||||
static void
|
||||
x11_init_platform(struct native_platform *nplat)
|
||||
{
|
||||
static char x11_name[32];
|
||||
|
||||
if (nplat->name)
|
||||
return;
|
||||
|
||||
util_snprintf(x11_name, sizeof(x11_name), "X11/%s", driver_descriptor.name);
|
||||
|
||||
nplat->name = x11_name;
|
||||
nplat->create_probe = x11_create_probe;
|
||||
nplat->get_probe_result = x11_get_probe_result;
|
||||
nplat->create_display = native_create_display;
|
||||
}
|
||||
|
||||
static struct native_platform x11_platform;
|
||||
static const struct native_platform x11_platform = {
|
||||
"X11", /* name */
|
||||
x11_create_probe,
|
||||
x11_get_probe_result,
|
||||
native_create_display
|
||||
};
|
||||
|
||||
const struct native_platform *
|
||||
native_get_x11_platform(void)
|
||||
{
|
||||
x11_init_platform(&x11_platform);
|
||||
return &x11_platform;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,12 @@
|
||||
|
||||
struct native_display *
|
||||
x11_create_ximage_display(Display *dpy,
|
||||
struct native_event_handler *event_handler);
|
||||
struct native_event_handler *event_handler,
|
||||
void *user_data);
|
||||
|
||||
struct native_display *
|
||||
x11_create_dri2_display(Display *dpy,
|
||||
struct native_event_handler *event_handler);
|
||||
struct native_event_handler *event_handler,
|
||||
void *user_data);
|
||||
|
||||
#endif /* _NATIVE_X11_H_ */
|
||||
|
||||
@@ -442,7 +442,8 @@ ximage_display_destroy(struct native_display *ndpy)
|
||||
|
||||
struct native_display *
|
||||
x11_create_ximage_display(Display *dpy,
|
||||
struct native_event_handler *event_handler)
|
||||
struct native_event_handler *event_handler,
|
||||
void *user_data)
|
||||
{
|
||||
struct ximage_display *xdpy;
|
||||
struct sw_winsys *winsys = NULL;
|
||||
@@ -462,6 +463,7 @@ x11_create_ximage_display(Display *dpy,
|
||||
}
|
||||
|
||||
xdpy->event_handler = event_handler;
|
||||
xdpy->base.user_data = user_data;
|
||||
|
||||
xdpy->xscr_number = DefaultScreen(xdpy->dpy);
|
||||
xdpy->xscr = x11_screen_create(xdpy->dpy, xdpy->xscr_number);
|
||||
@@ -472,7 +474,8 @@ x11_create_ximage_display(Display *dpy,
|
||||
if (!winsys)
|
||||
goto fail;
|
||||
|
||||
xdpy->base.screen = native_create_sw_screen(winsys);
|
||||
xdpy->base.screen =
|
||||
xdpy->event_handler->new_sw_screen(&xdpy->base, winsys);
|
||||
if (!xdpy->base.screen)
|
||||
goto fail;
|
||||
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
TOP = ../../../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
ST_PREFIX := st_
|
||||
PIPE_PREFIX := egl_gallium_
|
||||
|
||||
common_CPPFLAGS := \
|
||||
-I$(TOP)/src/gallium/auxiliary \
|
||||
-I$(TOP)/src/gallium/drivers \
|
||||
@@ -30,7 +33,8 @@ common_LIBS := \
|
||||
# EGL driver
|
||||
egl_CPPFLAGS := \
|
||||
-I$(TOP)/src/gallium/state_trackers/egl \
|
||||
-I$(TOP)/src/egl/main
|
||||
-I$(TOP)/src/egl/main \
|
||||
-DST_PREFIX=\"$(ST_PREFIX)\"
|
||||
egl_SYS := -lm -ldl -lEGL
|
||||
egl_LIBS := \
|
||||
$(TOP)/src/gallium/state_trackers/egl/libegl.a \
|
||||
@@ -47,6 +51,22 @@ ifneq ($(findstring fbdev, $(EGL_PLATFORMS)),)
|
||||
egl_LIBS += $(TOP)/src/gallium/winsys/sw/fbdev/libfbdev.a
|
||||
endif
|
||||
|
||||
# EGL_RENDERABLE_TYPE is a compile time attribute
|
||||
egl_CPPFLAGS += $(API_DEFINES)
|
||||
ifneq ($(filter $(GL_LIB), $(EGL_CLIENT_APIS)),)
|
||||
egl_CPPFLAGS += -DFEATURE_GL=1
|
||||
endif
|
||||
ifneq ($(filter $(GLESv1_CM_LIB), $(EGL_CLIENT_APIS)),)
|
||||
egl_CPPFLAGS += -DFEATURE_ES1=1
|
||||
endif
|
||||
ifneq ($(filter $(GLESv2_LIB), $(EGL_CLIENT_APIS)),)
|
||||
egl_CPPFLAGS += -DFEATURE_ES2=1
|
||||
endif
|
||||
ifneq ($(filter $(VG_LIB), $(EGL_CLIENT_APIS)),)
|
||||
egl_CPPFLAGS += -DFEATURE_VG=1
|
||||
endif
|
||||
egl_CPPFLAGS := $(sort $(egl_CPPFLAGS))
|
||||
|
||||
# LLVM
|
||||
ifeq ($(MESA_LLVM),1)
|
||||
common_SYS += $(LLVM_LIBS)
|
||||
@@ -136,10 +156,10 @@ ifneq ($(findstring svga,$(GALLIUM_WINSYS_DIRS)),)
|
||||
OUTPUTS += vmwgfx
|
||||
endif
|
||||
OUTPUTS += swrast
|
||||
OUTPUTS := $(addprefix egl_gallium_, $(OUTPUTS))
|
||||
OUTPUTS := $(addprefix $(PIPE_PREFIX), $(OUTPUTS))
|
||||
|
||||
# state trackers
|
||||
OUTPUTS += $(addprefix st_, $(EGL_CLIENT_APIS))
|
||||
OUTPUTS += $(addprefix $(ST_PREFIX), $(EGL_CLIENT_APIS))
|
||||
|
||||
OUTPUTS := $(addsuffix .so, $(OUTPUTS))
|
||||
OUTPUTS := $(addprefix $(OUTPUT_PATH)/, $(OUTPUTS))
|
||||
@@ -148,7 +168,7 @@ default: $(OUTPUTS)
|
||||
|
||||
define mklib-egl
|
||||
$(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
-install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< \
|
||||
-install $(OUTPUT_PATH) $(MKLIB_OPTIONS) $< egl.o \
|
||||
-Wl,--start-group $(common_LIBS) $(egl_LIBS) $($(1)_LIBS) -Wl,--end-group \
|
||||
$(common_SYS) $(egl_SYS) $($(1)_SYS)
|
||||
endef
|
||||
@@ -161,37 +181,40 @@ $(MKLIB) -o $(notdir $@) -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
|
||||
endef
|
||||
|
||||
# EGL drivers
|
||||
$(OUTPUT_PATH)/egl_gallium_i915.so: pipe_i915.o $(egl_LIBS) $(i915_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)i915.so: pipe_i915.o egl.o $(egl_LIBS) $(i915_LIBS)
|
||||
$(call mklib-egl,i915)
|
||||
|
||||
$(OUTPUT_PATH)/egl_gallium_i965.so: pipe_i965.o $(egl_LIBS) $(i965_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)i965.so: pipe_i965.o egl.o $(egl_LIBS) $(i965_LIBS)
|
||||
$(call mklib-egl,i965)
|
||||
|
||||
$(OUTPUT_PATH)/egl_gallium_nouveau.so: pipe_nouveau.o $(egl_LIBS) $(nouveau_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)nouveau.so: pipe_nouveau.o egl.o $(egl_LIBS) $(nouveau_LIBS)
|
||||
$(call mklib-egl,nouveau)
|
||||
|
||||
$(OUTPUT_PATH)/egl_gallium_radeon.so: pipe_radeon.o $(egl_LIBS) $(radeon_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)radeon.so: pipe_radeon.o egl.o $(egl_LIBS) $(radeon_LIBS)
|
||||
$(call mklib-egl,radeon)
|
||||
|
||||
$(OUTPUT_PATH)/egl_gallium_vmwgfx.so: pipe_vmwgfx.o $(egl_LIBS) $(vmwgfx_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)vmwgfx.so: pipe_vmwgfx.o egl.o $(egl_LIBS) $(vmwgfx_LIBS)
|
||||
$(call mklib-egl,vmwgfx)
|
||||
|
||||
$(OUTPUT_PATH)/egl_gallium_swrast.so: pipe_swrast.o $(egl_LIBS) $(swrast_LIBS)
|
||||
$(OUTPUT_PATH)/$(PIPE_PREFIX)swrast.so: pipe_swrast.o egl.o $(egl_LIBS) $(swrast_LIBS)
|
||||
$(call mklib-egl,swrast)
|
||||
|
||||
# state trackers
|
||||
$(OUTPUT_PATH)/st_$(GL_LIB).so: st_GL.o $(GL_LIBS)
|
||||
$(OUTPUT_PATH)/$(ST_PREFIX)$(GL_LIB).so: st_GL.o $(GL_LIBS)
|
||||
$(call mklib,GL)
|
||||
|
||||
$(OUTPUT_PATH)/st_$(GLESv1_CM_LIB).so: st_GLESv1_CM.o $(GLESv1_CM_LIBS)
|
||||
$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv1_CM_LIB).so: st_GLESv1_CM.o $(GLESv1_CM_LIBS)
|
||||
$(call mklib,GLESv1_CM)
|
||||
|
||||
$(OUTPUT_PATH)/st_$(GLESv2_LIB).so: st_GLESv2.o $(GLESv2_LIBS)
|
||||
$(OUTPUT_PATH)/$(ST_PREFIX)$(GLESv2_LIB).so: st_GLESv2.o $(GLESv2_LIBS)
|
||||
$(call mklib,GLESv2)
|
||||
|
||||
$(OUTPUT_PATH)/st_$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS)
|
||||
$(OUTPUT_PATH)/$(ST_PREFIX)$(VG_LIB).so: st_OpenVG.o $(OpenVG_LIBS)
|
||||
$(call mklib,OpenVG)
|
||||
|
||||
egl.o: egl.c
|
||||
$(CC) -c -o $@ $< $(common_CPPFLAGS) $(egl_CPPFLAGS) $(DEFINES) $(CFLAGS)
|
||||
|
||||
pipe_%.o: pipe_%.c
|
||||
$(CC) -c -o $@ $< $(common_CPPFLAGS) $($*_CPPFLAGS) $(DEFINES) $(CFLAGS)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ if env['platform'] == 'windows':
|
||||
|
||||
egl_gallium_swrast = env.SharedLibrary(
|
||||
target ='egl_gallium_swrast',
|
||||
source = 'pipe_swrast.c',
|
||||
source = ['egl.c', 'pipe_swrast.c'],
|
||||
LIBS = st_egl_gdi + ws_gdi + drivers + gallium + egl + env['LIBS'],
|
||||
)
|
||||
|
||||
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
* Version: 7.9
|
||||
*
|
||||
* Copyright (C) 2010 LunarG Inc.
|
||||
*
|
||||
* 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, sublicense,
|
||||
* 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 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.
|
||||
*
|
||||
* Authors:
|
||||
* Chia-I Wu <olv@lunarg.com>
|
||||
*/
|
||||
|
||||
#include "util/u_debug.h"
|
||||
#include "util/u_string.h"
|
||||
#include "util/u_memory.h"
|
||||
#include "util/u_dl.h"
|
||||
#include "egldriver.h"
|
||||
#include "egllog.h"
|
||||
|
||||
#include "state_tracker/st_api.h"
|
||||
#include "softpipe/sp_public.h"
|
||||
#include "llvmpipe/lp_public.h"
|
||||
#include "target-helpers/wrap_screen.h"
|
||||
#include "common/egl_g3d_loader.h"
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
struct egl_g3d_loader egl_g3d_loader;
|
||||
|
||||
static struct st_module {
|
||||
boolean initialized;
|
||||
const char *name;
|
||||
struct util_dl_library *lib;
|
||||
struct st_api *stapi;
|
||||
} st_modules[ST_API_COUNT];
|
||||
|
||||
static EGLBoolean
|
||||
dlopen_st_module_cb(const char *dir, size_t len, void *callback_data)
|
||||
{
|
||||
struct st_module *stmod =
|
||||
(struct st_module *) callback_data;
|
||||
char path[1024];
|
||||
int ret;
|
||||
|
||||
if (len) {
|
||||
ret = util_snprintf(path, sizeof(path),
|
||||
"%.*s/" ST_PREFIX "%s" UTIL_DL_EXT, len, dir, stmod->name);
|
||||
}
|
||||
else {
|
||||
ret = util_snprintf(path, sizeof(path),
|
||||
ST_PREFIX "%s" UTIL_DL_EXT, stmod->name);
|
||||
}
|
||||
|
||||
if (ret > 0 && ret < sizeof(path)) {
|
||||
stmod->lib = util_dl_open(path);
|
||||
if (stmod->lib)
|
||||
_eglLog(_EGL_DEBUG, "loaded %s", path);
|
||||
}
|
||||
|
||||
return !(stmod->lib);
|
||||
}
|
||||
|
||||
static boolean
|
||||
load_st_module(struct st_module *stmod,
|
||||
const char *name, const char *procname)
|
||||
{
|
||||
struct st_api *(*create_api)(void);
|
||||
|
||||
stmod->name = name;
|
||||
if (stmod->name)
|
||||
_eglSearchPathForEach(dlopen_st_module_cb, (void *) stmod);
|
||||
else
|
||||
stmod->lib = util_dl_open(NULL);
|
||||
|
||||
if (stmod->lib) {
|
||||
create_api = (struct st_api *(*)(void))
|
||||
util_dl_get_proc_address(stmod->lib, procname);
|
||||
if (create_api)
|
||||
stmod->stapi = create_api();
|
||||
|
||||
if (!stmod->stapi) {
|
||||
util_dl_close(stmod->lib);
|
||||
stmod->lib = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!stmod->stapi)
|
||||
stmod->name = NULL;
|
||||
|
||||
return (stmod->stapi != NULL);
|
||||
}
|
||||
|
||||
static struct st_api *
|
||||
get_st_api(enum st_api_type api)
|
||||
{
|
||||
struct st_module *stmod = &st_modules[api];
|
||||
const char *names[8], *symbol;
|
||||
int i, count = 0;
|
||||
|
||||
if (stmod->initialized)
|
||||
return stmod->stapi;
|
||||
|
||||
switch (api) {
|
||||
case ST_API_OPENGL:
|
||||
symbol = ST_CREATE_OPENGL_SYMBOL;
|
||||
names[count++] = "GL";
|
||||
break;
|
||||
case ST_API_OPENGL_ES1:
|
||||
symbol = ST_CREATE_OPENGL_ES1_SYMBOL;
|
||||
names[count++] = "GLESv1_CM";
|
||||
names[count++] = "GL";
|
||||
break;
|
||||
case ST_API_OPENGL_ES2:
|
||||
symbol = ST_CREATE_OPENGL_ES2_SYMBOL;
|
||||
names[count++] = "GLESv2";
|
||||
names[count++] = "GL";
|
||||
break;
|
||||
case ST_API_OPENVG:
|
||||
symbol = ST_CREATE_OPENVG_SYMBOL;
|
||||
names[count++] = "OpenVG";
|
||||
break;
|
||||
default:
|
||||
symbol = NULL;
|
||||
assert(!"Unknown API Type\n");
|
||||
break;
|
||||
}
|
||||
|
||||
/* NULL means the process itself */
|
||||
names[count++] = NULL;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (load_st_module(stmod, names[i], symbol))
|
||||
break;
|
||||
}
|
||||
|
||||
if (!stmod->stapi) {
|
||||
EGLint level = (egl_g3d_loader.api_mask & (1 << api)) ?
|
||||
_EGL_WARNING : _EGL_DEBUG;
|
||||
_eglLog(level, "unable to load " ST_PREFIX "%s" UTIL_DL_EXT, names[0]);
|
||||
}
|
||||
|
||||
stmod->initialized = TRUE;
|
||||
|
||||
return stmod->stapi;
|
||||
}
|
||||
|
||||
static struct st_api *
|
||||
guess_gl_api(void)
|
||||
{
|
||||
struct st_api *stapi;
|
||||
int gl_apis[] = {
|
||||
ST_API_OPENGL,
|
||||
ST_API_OPENGL_ES1,
|
||||
ST_API_OPENGL_ES2,
|
||||
-1
|
||||
};
|
||||
int i, api = -1;
|
||||
|
||||
/* determine the api from the loaded libraries */
|
||||
for (i = 0; gl_apis[i] != -1; i++) {
|
||||
if (st_modules[gl_apis[i]].stapi) {
|
||||
api = gl_apis[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* determine the api from the linked libraries */
|
||||
if (api == -1) {
|
||||
struct util_dl_library *self = util_dl_open(NULL);
|
||||
|
||||
if (self) {
|
||||
if (util_dl_get_proc_address(self, "glColor4d"))
|
||||
api = ST_API_OPENGL;
|
||||
else if (util_dl_get_proc_address(self, "glColor4x"))
|
||||
api = ST_API_OPENGL_ES1;
|
||||
else if (util_dl_get_proc_address(self, "glShaderBinary"))
|
||||
api = ST_API_OPENGL_ES2;
|
||||
util_dl_close(self);
|
||||
}
|
||||
}
|
||||
|
||||
stapi = (api != -1) ? get_st_api(api) : NULL;
|
||||
if (!stapi) {
|
||||
for (i = 0; gl_apis[i] != -1; i++) {
|
||||
api = gl_apis[i];
|
||||
stapi = get_st_api(api);
|
||||
if (stapi)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return stapi;
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
create_drm_screen(const char *name, int fd)
|
||||
{
|
||||
return (driver_descriptor.driver_name && name &&
|
||||
strcmp(driver_descriptor.driver_name, name) == 0) ?
|
||||
driver_descriptor.create_screen(fd) : NULL;
|
||||
}
|
||||
|
||||
static struct pipe_screen *
|
||||
create_sw_screen(struct sw_winsys *ws)
|
||||
{
|
||||
struct pipe_screen *screen = NULL;
|
||||
|
||||
#if defined(GALLIUM_LLVMPIPE)
|
||||
if (!screen && !debug_get_bool_option("GALLIUM_NO_LLVM", FALSE))
|
||||
screen = llvmpipe_create_screen(ws);
|
||||
#endif
|
||||
if (!screen)
|
||||
screen = softpipe_create_screen(ws);
|
||||
|
||||
return (screen) ? gallium_wrap_screen(screen) : NULL;
|
||||
}
|
||||
|
||||
static const struct egl_g3d_loader *
|
||||
loader_init(void)
|
||||
{
|
||||
uint api_mask = 0x0;
|
||||
|
||||
/* TODO detect at runtime? */
|
||||
#if FEATURE_GL
|
||||
api_mask |= 1 << ST_API_OPENGL;
|
||||
#endif
|
||||
#if FEATURE_ES1
|
||||
api_mask |= 1 << ST_API_OPENGL_ES1;
|
||||
#endif
|
||||
#if FEATURE_ES2
|
||||
api_mask |= 1 << ST_API_OPENGL_ES2;
|
||||
#endif
|
||||
#if FEATURE_VG
|
||||
api_mask |= 1 << ST_API_OPENVG;
|
||||
#endif
|
||||
|
||||
egl_g3d_loader.api_mask = api_mask;
|
||||
egl_g3d_loader.get_st_api = get_st_api;
|
||||
egl_g3d_loader.guess_gl_api = guess_gl_api;
|
||||
egl_g3d_loader.create_drm_screen = create_drm_screen;
|
||||
egl_g3d_loader.create_sw_screen = create_sw_screen;
|
||||
|
||||
return &egl_g3d_loader;
|
||||
}
|
||||
|
||||
static void
|
||||
loader_fini(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ST_API_COUNT; i++) {
|
||||
struct st_module *stmod = &st_modules[i];
|
||||
|
||||
if (stmod->stapi) {
|
||||
stmod->stapi->destroy(stmod->stapi);
|
||||
stmod->stapi = NULL;
|
||||
}
|
||||
if (stmod->lib) {
|
||||
util_dl_close(stmod->lib);
|
||||
stmod->lib = NULL;
|
||||
}
|
||||
stmod->name = NULL;
|
||||
stmod->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
egl_g3d_unload(_EGLDriver *drv)
|
||||
{
|
||||
egl_g3d_destroy_driver(drv);
|
||||
loader_fini();
|
||||
}
|
||||
|
||||
_EGLDriver *
|
||||
_eglMain(const char *args)
|
||||
{
|
||||
const struct egl_g3d_loader *loader;
|
||||
_EGLDriver *drv;
|
||||
|
||||
loader = loader_init();
|
||||
drv = egl_g3d_create_driver(loader);
|
||||
if (!drv) {
|
||||
loader_fini();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
drv->Name = "Gallium";
|
||||
drv->Unload = egl_g3d_unload;
|
||||
|
||||
return drv;
|
||||
}
|
||||
@@ -28,7 +28,3 @@ create_screen(int fd)
|
||||
}
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR("i965", "i965", create_screen)
|
||||
|
||||
/* A poor man's --whole-archive for EGL drivers */
|
||||
void *_eglMain(void *);
|
||||
void *_eglWholeArchive = (void *) _eglMain;
|
||||
|
||||
@@ -18,7 +18,3 @@ create_screen(int fd)
|
||||
}
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR("nouveau", "nouveau", create_screen)
|
||||
|
||||
/* A poor man's --whole-archive for EGL drivers */
|
||||
void *_eglMain(void *);
|
||||
void *_eglWholeArchive = (void *) _eglMain;
|
||||
|
||||
@@ -24,7 +24,3 @@ create_screen(int fd)
|
||||
}
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR("radeon", "radeon", create_screen)
|
||||
|
||||
/* A poor man's --whole-archive for EGL drivers */
|
||||
void *_eglMain(void *);
|
||||
void *_eglWholeArchive = (void *) _eglMain;
|
||||
|
||||
@@ -2,7 +2,3 @@
|
||||
#include "state_tracker/drm_driver.h"
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR("swrast", NULL, NULL)
|
||||
|
||||
/* A poor man's --whole-archive for EGL drivers */
|
||||
void *_eglMain(void *);
|
||||
void *_eglWholeArchive = (void *) _eglMain;
|
||||
|
||||
@@ -24,7 +24,3 @@ create_screen(int fd)
|
||||
}
|
||||
|
||||
DRM_DRIVER_DESCRIPTOR("vmwgfx", "vmwgfx", create_screen)
|
||||
|
||||
/* A poor man's --whole-archive for EGL drivers */
|
||||
void *_eglMain(void *);
|
||||
void *_eglWholeArchive = (void *) _eglMain;
|
||||
|
||||
Reference in New Issue
Block a user