diff options
author | Chia-I Wu <olvaffe@gmail.com> | 2010-02-04 10:55:33 +0800 |
---|---|---|
committer | Chia-I Wu <olvaffe@gmail.com> | 2010-02-04 10:55:33 +0800 |
commit | fcceafbcb67f97264d3e880ac4389770a2799454 (patch) | |
tree | e03181d5c374ef18d74aa68c7e1a5f4e399ff409 /sample-implementation-tmp | |
parent | 7d56fc70b15ff52658a3e6c416f5c1699a8b670c (diff) |
Add a sample implementation.
Diffstat (limited to 'sample-implementation-tmp')
5 files changed, 2391 insertions, 0 deletions
diff --git a/sample-implementation-tmp/0001-gallium-Add-st_api.h.patch b/sample-implementation-tmp/0001-gallium-Add-st_api.h.patch new file mode 100644 index 0000000..98f1372 --- /dev/null +++ b/sample-implementation-tmp/0001-gallium-Add-st_api.h.patch @@ -0,0 +1,420 @@ +From 94e420c2b04c3e14a920106d117a94aaf74404b2 Mon Sep 17 00:00:00 2001 +From: Chia-I Wu <olvaffe@gmail.com> +Date: Wed, 13 Jan 2010 17:57:35 +0800 +Subject: [PATCH 1/5] gallium: Add st_api.h. + +--- + src/gallium/include/state_tracker/st_api.h | 401 ++++++++++++++++++++++++++++ + 1 files changed, 401 insertions(+), 0 deletions(-) + create mode 100644 src/gallium/include/state_tracker/st_api.h + +diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h +new file mode 100644 +index 0000000..8feaade +--- /dev/null ++++ b/src/gallium/include/state_tracker/st_api.h +@@ -0,0 +1,401 @@ ++/********************************************************** ++ * Copyright 2010 VMware, 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, 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. ++ * ++ **********************************************************/ ++ ++ ++#ifndef _ST_API_H_ ++#define _ST_API_H_ ++ ++#include "pipe/p_compiler.h" ++#include "pipe/p_format.h" ++ ++/** ++ * \file API for communication between state trackers and state tracker ++ * managers. ++ * ++ * While both are state tackers, we use the term state tracker for rendering ++ * APIs such as OpenGL or OpenVG, and state tracker manager for window system ++ * APIs such as EGL or GLX in this file. ++ * ++ * This file defines an API to be implemented by both state trackers and state ++ * tracker managers. ++ */ ++ ++/** ++ * The entry points of the state trackers. ++ */ ++#define ST_MODULE_OPENGL_SYMBOL "st_module_OpenGL" ++#define ST_MODULE_OPENGL_ES1_SYMBOL "st_module_OpenGL_ES1" ++#define ST_MODULE_OPENGL_ES2_SYMBOL "st_module_OpenGL_ES2" ++#define ST_MODULE_OPENVG_SYMBOL "st_module_OpenVG" ++ ++/** ++ * The supported rendering API of a state tracker. ++ */ ++enum st_api_type { ++ ST_API_OPENGL, ++ ST_API_OPENGL_ES1, ++ ST_API_OPENGL_ES2, ++ ST_API_OPENVG, ++ ++ ST_API_COUNT ++}; ++ ++/** ++ * Used in st_context->teximage. ++ */ ++enum st_texture_type { ++ ST_TEXTURE_1D, ++ ST_TEXTURE_2D, ++ ST_TEXTURE_3D, ++ ST_TEXTURE_RECT, ++}; ++ ++/** ++ * Available attachments of framebuffer. ++ */ ++enum st_attachment_type { ++ ST_ATTACHMENT_FRONT_LEFT, ++ ST_ATTACHMENT_BACK_LEFT, ++ ST_ATTACHMENT_FRONT_RIGHT, ++ ST_ATTACHMENT_BACK_RIGHT, ++ ST_ATTACHMENT_DEPTH_STENCIL, ++ ST_ATTACHMENT_ACCUM, ++ ST_ATTACHMENT_SAMPLE, ++ ++ ST_ATTACHMENT_COUNT, ++ ST_ATTACHMENT_INVALID = -1 ++}; ++ ++/* for buffer_mask in st_visual */ ++#define ST_ATTACHMENT_FRONT_LEFT_MASK (1 << ST_ATTACHMENT_FRONT_LEFT) ++#define ST_ATTACHMENT_BACK_LEFT_MASK (1 << ST_ATTACHMENT_BACK_LEFT) ++#define ST_ATTACHMENT_FRONT_RIGHT_MASK (1 << ST_ATTACHMENT_FRONT_RIGHT) ++#define ST_ATTACHMENT_BACK_RIGHT_MASK (1 << ST_ATTACHMENT_BACK_RIGHT) ++#define ST_ATTACHMENT_DEPTH_STENCIL_MASK (1 << ST_ATTACHMENT_DEPTH_STENCIL) ++#define ST_ATTACHMENT_ACCUM_MASK (1 << ST_ATTACHMENT_ACCUM) ++#define ST_ATTACHMENT_SAMPLE_MASK (1 << ST_ATTACHMENT_SAMPLE) ++ ++/** ++ * Enumerations of state tracker manager resources. ++ */ ++enum st_manager_resource_type { ++ /* return struct pipe_surface (this is likely to change) */ ++ ST_MANAGER_RESOURCE_EGL_IMAGE, ++}; ++ ++/** ++ * Enumerations of state tracker context resources. ++ */ ++enum st_context_resource_type { ++ /* all of them return struct pipe_texture */ ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_2D, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_3D, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_X, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_X, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Y, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Y, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_POSITIVE_Z, ++ ST_CONTEXT_RESOURCE_OPENGL_TEXTURE_CUBE_MAP_NEGATIVE_Z, ++ ST_CONTEXT_RESOURCE_OPENGL_RENDERBUFFER, ++ ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE, ++}; ++ ++/** ++ * The return type of st_api->get_proc_address. ++ */ ++typedef void (*st_proc_t)(void); ++ ++struct pipe_context; ++struct pipe_texture; ++struct pipe_fence_handle; ++ ++/** ++ * Represent the visual of a framebuffer. ++ */ ++struct st_visual ++{ ++ /** ++ * Available buffers. Tested with ST_FRAMEBUFFER_*_MASK. ++ */ ++ unsigned buffer_mask; ++ ++ /** ++ * Buffer formats. The formats are always set even when the buffer is ++ * not available. ++ */ ++ enum pipe_format color_format; ++ enum pipe_format depth_stencil_format; ++ enum pipe_format accum_format; ++ int samples; ++ ++ /** ++ * Desired render buffer. ++ */ ++ enum st_attachment_type render_buffer; ++}; ++ ++/** ++ * Represent a windowing system drawable. ++ * ++ * The framebuffer is implemented by the state tracker manager and ++ * used by the state trackers. ++ * ++ * Instead of the winsys pokeing into the API context to figure ++ * out what buffers that might be needed in the future by the API ++ * context, it calls into the framebuffer to get the textures. ++ * ++ * This structure along with the notify_invalid_framebuffer ++ * allows framebuffers to be shared between different threads ++ * but at the same make the API context free from thread ++ * syncronisation primitves, with the exception of a small ++ * atomic flag used for notification of framebuffer dirty status. ++ * ++ * The thread syncronisation is put inside the framebuffer ++ * and only called once the framebuffer has become dirty. ++ */ ++struct st_framebuffer ++{ ++ /** ++ * Available for the state tracker manager to use. ++ */ ++ void *st_manager_private; ++ ++ /** ++ * The visual of a framebuffer. ++ */ ++ const struct st_visual *visual; ++ ++ /** ++ * Flush the front buffer. ++ * ++ * On some window systems, changes to the front buffers are not immediately ++ * visible. They need to be flushed. ++ * ++ * @att is one of the front buffer attachments. ++ */ ++ boolean (*flush_front)(struct st_framebuffer *stfb, ++ enum st_attachment_type statt); ++ ++ /** ++ * The state tracker asks for the textures it needs. ++ * ++ * It should try to only ask for attachments that it currently renders ++ * to, thus allowing the winsys to delay the allocation of textures not ++ * needed. For example front buffer attachments are not needed if you ++ * only do back buffer rendering. ++ * ++ * The implementor of this function needs to also ensure ++ * thread safty as this call might be done from multiple threads. ++ * ++ * The returned textures are owned by the caller. They should be ++ * unreferenced when no longer used. If this function is called multiple ++ * times with different sets of attachments, those buffers not included in ++ * the last call might be destroyed. This behavior might change in the ++ * future. ++ */ ++ boolean (*validate)(struct st_framebuffer *stfb, ++ const enum st_attachment_type *statts, ++ unsigned count, ++ struct pipe_texture **out); ++}; ++ ++/** ++ * Represent a rendering context. ++ * ++ * This entity is created from st_api and used by the state tracker manager. ++ */ ++struct st_context ++{ ++ /** ++ * The API of the context. ++ */ ++ enum st_api_type api; ++ ++ /** ++ * Available for the state tracker to use. ++ */ ++ void *st_api_private; ++ ++ /** ++ * Destroy the context. ++ */ ++ void (*destroy)(struct st_context *stctx); ++ ++ /** ++ * Lock and unlock a state tracker context resource. ++ * ++ * This gives access to the underlying data structure of a state tracker ++ * context resource. Unless there is some mechanism not defined here that ++ * can lengthen the lifetime of the data structure, it is valid only until ++ * unlocked. ++ */ ++ void *(*lock_resource)(struct st_context *stctx, ++ enum st_context_resource_type type, void *res); ++ void (*unlock_resource)(struct st_context *stctx, ++ enum st_context_resource_type type, void *res); ++ ++ /** ++ * Invalidate the current textures that was taken from a framebuffer. ++ * ++ * The state tracker manager calls this function to let the rendering ++ * context know that it should update the textures it got from ++ * st_framebuffer::validate. It should do so at the latest time possible. ++ * Possible right before sending triangles to the pipe context. ++ * ++ * For certain platforms this function might be called from a thread other ++ * than the thread that the context is currently bound in, and must ++ * therefore be thread safe. But it is the state tracker manager's ++ * responsibility to make sure that the framebuffer is bound to the context ++ * and the API context is current for the duration of this call. ++ * ++ * Thus reducing the sync primitive needed to a single atomic flag. ++ */ ++ void (*notify_invalid_framebuffer)(struct st_context *stctx, ++ struct st_framebuffer *stfb); ++ ++ /** ++ * Flush all drawing from context to the pipe also flushes the pipe. ++ */ ++ void (*flush)(struct st_context *stctx, unsigned flags, ++ struct pipe_fence_handle **fence); ++ ++ /** ++ * Replace the texture image of a texture object at the specified level. ++ * ++ * This function is optional. ++ */ ++ boolean (*teximage)(struct st_context *stctx, enum st_texture_type target, ++ int level, enum pipe_format internal_format, ++ struct pipe_texture *tex, boolean mipmap); ++ ++ /** ++ * Used to implement glXCopyContext. ++ */ ++ void (*copy)(struct st_context *stctx, struct st_context *stsrc, ++ unsigned mask); ++}; ++ ++ ++/** ++ * Represent a state tracker manager. ++ * ++ * This interface is implemented by the state tracker manager. It corresponds ++ * to a "display" in the window system. ++ */ ++struct st_manager ++{ ++ /** ++ * Lock and unlock a state tracker manager resource. ++ * ++ * This gives access to the underlying data structure of a state tracker ++ * manager resource. Unless there is some mechanism not defined here that ++ * can lengthen the lifetime of the data structure, it is valid only until ++ * unlocked. ++ */ ++ void *(*lock_resource)(struct st_manager *smapi, struct st_context *stctx, ++ enum st_manager_resource_type type, void *res); ++ void (*unlock_resource)(struct st_manager *smapi, struct st_context *stctx, ++ enum st_manager_resource_type type, void *res); ++}; ++ ++/** ++ * Represent a rendering API such as OpenGL or OpenVG. ++ * ++ * Implemented by the state tracker and used by the state tracker manager. ++ */ ++struct st_api ++{ ++ /** ++ * Destroy the API. ++ */ ++ void (*destroy)(struct st_api *stapi); ++ ++ /** ++ * Return an API entry point. ++ * ++ * For GL this is the same as _glapi_get_proc_address. ++ */ ++ st_proc_t (*get_proc_address)(struct st_api *stapi, const char *procname); ++ ++ /** ++ * Return true if the visual is supported by the state tracker. ++ */ ++ boolean (*is_visual_supported)(struct st_api *stapi, ++ const struct st_visual *visual); ++ ++ /** ++ * Create a rendering context. ++ * ++ * XXX: The pipe argument should go away once ++ * the pipe_screen can create contexts. ++ * XXX: Is visual needed? ++ */ ++ struct st_context *(*create_context)(struct st_api *stapi, ++ struct st_manager *smapi, ++ struct pipe_context *pipe, ++ const struct st_visual *visual, ++ struct st_context *stshare); ++ ++ /** ++ * Bind the context to the calling thread with draw and read as drawables. ++ */ ++ boolean (*make_current)(struct st_api *stapi, ++ struct st_context *stctx, ++ struct st_framebuffer *stdraw, ++ struct st_framebuffer *stread); ++ ++ /** ++ * Get the currently bound context in the calling thread. ++ */ ++ struct st_context *(*get_current)(struct st_api *stapi); ++}; ++ ++/** ++ * Represent a state tracker. ++ * ++ * This is the entry point of a state tracker. ++ */ ++struct st_module ++{ ++ enum st_api_type api; ++ struct st_api *(*create_api)(void); ++}; ++ ++/** ++ * Return true if the visual has the specified buffers. ++ */ ++static INLINE boolean ++st_visual_have_buffers(const struct st_visual *visual, unsigned mask) ++{ ++ return ((visual->buffer_mask & mask) == mask); ++} ++ ++/* these symbols may need to be dynamically lookup up */ ++extern PUBLIC const struct st_module st_module_OpenGL; ++extern PUBLIC const struct st_module st_module_OpenGL_ES1; ++extern PUBLIC const struct st_module st_module_OpenGL_ES2; ++extern PUBLIC const struct st_module st_module_OpenVG; ++ ++#endif /* _ST_API_H_ */ +-- +1.6.5 + diff --git a/sample-implementation-tmp/0002-gallium-Suffix-st_framebuffer-and-st_context-with-_i.patch b/sample-implementation-tmp/0002-gallium-Suffix-st_framebuffer-and-st_context-with-_i.patch new file mode 100644 index 0000000..22990fd --- /dev/null +++ b/sample-implementation-tmp/0002-gallium-Suffix-st_framebuffer-and-st_context-with-_i.patch @@ -0,0 +1,175 @@ +From e2bd293a0f9c775487ea007c72ba9feca2a52afc Mon Sep 17 00:00:00 2001 +From: Chia-I Wu <olvaffe@gmail.com> +Date: Tue, 2 Feb 2010 13:45:53 +0800 +Subject: [PATCH 2/5] gallium: Suffix st_framebuffer and st_context with _iface. + +--- + src/gallium/include/state_tracker/st_api.h | 54 ++++++++++++++------------- + 1 files changed, 28 insertions(+), 26 deletions(-) + +diff --git a/src/gallium/include/state_tracker/st_api.h b/src/gallium/include/state_tracker/st_api.h +index 8feaade..5a47b63 100644 +--- a/src/gallium/include/state_tracker/st_api.h ++++ b/src/gallium/include/state_tracker/st_api.h +@@ -63,7 +63,7 @@ enum st_api_type { + }; + + /** +- * Used in st_context->teximage. ++ * Used in st_context_iface->teximage. + */ + enum st_texture_type { + ST_TEXTURE_1D, +@@ -175,7 +175,7 @@ struct st_visual + * The thread syncronisation is put inside the framebuffer + * and only called once the framebuffer has become dirty. + */ +-struct st_framebuffer ++struct st_framebuffer_iface + { + /** + * Available for the state tracker manager to use. +@@ -195,7 +195,7 @@ struct st_framebuffer + * + * @att is one of the front buffer attachments. + */ +- boolean (*flush_front)(struct st_framebuffer *stfb, ++ boolean (*flush_front)(struct st_framebuffer_iface *stfbi, + enum st_attachment_type statt); + + /** +@@ -215,7 +215,7 @@ struct st_framebuffer + * the last call might be destroyed. This behavior might change in the + * future. + */ +- boolean (*validate)(struct st_framebuffer *stfb, ++ boolean (*validate)(struct st_framebuffer_iface *stfbi, + const enum st_attachment_type *statts, + unsigned count, + struct pipe_texture **out); +@@ -226,7 +226,7 @@ struct st_framebuffer + * + * This entity is created from st_api and used by the state tracker manager. + */ +-struct st_context ++struct st_context_iface + { + /** + * The API of the context. +@@ -241,7 +241,7 @@ struct st_context + /** + * Destroy the context. + */ +- void (*destroy)(struct st_context *stctx); ++ void (*destroy)(struct st_context_iface *stctxi); + + /** + * Lock and unlock a state tracker context resource. +@@ -251,9 +251,9 @@ struct st_context + * can lengthen the lifetime of the data structure, it is valid only until + * unlocked. + */ +- void *(*lock_resource)(struct st_context *stctx, ++ void *(*lock_resource)(struct st_context_iface *stctxi, + enum st_context_resource_type type, void *res); +- void (*unlock_resource)(struct st_context *stctx, ++ void (*unlock_resource)(struct st_context_iface *stctxi, + enum st_context_resource_type type, void *res); + + /** +@@ -261,7 +261,7 @@ struct st_context + * + * The state tracker manager calls this function to let the rendering + * context know that it should update the textures it got from +- * st_framebuffer::validate. It should do so at the latest time possible. ++ * st_framebuffer_iface::validate. It should do so at the latest time possible. + * Possible right before sending triangles to the pipe context. + * + * For certain platforms this function might be called from a thread other +@@ -272,13 +272,13 @@ struct st_context + * + * Thus reducing the sync primitive needed to a single atomic flag. + */ +- void (*notify_invalid_framebuffer)(struct st_context *stctx, +- struct st_framebuffer *stfb); ++ void (*notify_invalid_framebuffer)(struct st_context_iface *stctxi, ++ struct st_framebuffer_iface *stfbi); + + /** + * Flush all drawing from context to the pipe also flushes the pipe. + */ +- void (*flush)(struct st_context *stctx, unsigned flags, ++ void (*flush)(struct st_context_iface *stctxi, unsigned flags, + struct pipe_fence_handle **fence); + + /** +@@ -286,15 +286,15 @@ struct st_context + * + * This function is optional. + */ +- boolean (*teximage)(struct st_context *stctx, enum st_texture_type target, ++ boolean (*teximage)(struct st_context_iface *stctxi, enum st_texture_type target, + int level, enum pipe_format internal_format, + struct pipe_texture *tex, boolean mipmap); + + /** + * Used to implement glXCopyContext. + */ +- void (*copy)(struct st_context *stctx, struct st_context *stsrc, +- unsigned mask); ++ void (*copy)(struct st_context_iface *stctxi, ++ struct st_context_iface *stsrci, unsigned mask); + }; + + +@@ -314,9 +314,11 @@ struct st_manager + * can lengthen the lifetime of the data structure, it is valid only until + * unlocked. + */ +- void *(*lock_resource)(struct st_manager *smapi, struct st_context *stctx, ++ void *(*lock_resource)(struct st_manager *smapi, ++ struct st_context_iface *stctxi, + enum st_manager_resource_type type, void *res); +- void (*unlock_resource)(struct st_manager *smapi, struct st_context *stctx, ++ void (*unlock_resource)(struct st_manager *smapi, ++ struct st_context_iface *stctxi, + enum st_manager_resource_type type, void *res); + }; + +@@ -352,24 +354,24 @@ struct st_api + * the pipe_screen can create contexts. + * XXX: Is visual needed? + */ +- struct st_context *(*create_context)(struct st_api *stapi, +- struct st_manager *smapi, +- struct pipe_context *pipe, +- const struct st_visual *visual, +- struct st_context *stshare); ++ struct st_context_iface *(*create_context)(struct st_api *stapi, ++ struct st_manager *smapi, ++ struct pipe_context *pipe, ++ const struct st_visual *visual, ++ struct st_context_iface *stsharei); + + /** + * Bind the context to the calling thread with draw and read as drawables. + */ + boolean (*make_current)(struct st_api *stapi, +- struct st_context *stctx, +- struct st_framebuffer *stdraw, +- struct st_framebuffer *stread); ++ struct st_context_iface *stctxi, ++ struct st_framebuffer_iface *stdrawi, ++ struct st_framebuffer_iface *streadi); + + /** + * Get the currently bound context in the calling thread. + */ +- struct st_context *(*get_current)(struct st_api *stapi); ++ struct st_context_iface *(*get_current)(struct st_api *stapi); + }; + + /** +-- +1.6.5 + diff --git a/sample-implementation-tmp/0003-st-vega-Implement-st_api-interface.patch b/sample-implementation-tmp/0003-st-vega-Implement-st_api-interface.patch new file mode 100644 index 0000000..4e47567 --- /dev/null +++ b/sample-implementation-tmp/0003-st-vega-Implement-st_api-interface.patch @@ -0,0 +1,504 @@ +From 9cb428781f56af4e210669ed6a1cfd6381932aac Mon Sep 17 00:00:00 2001 +From: Chia-I Wu <olvaffe@gmail.com> +Date: Thu, 14 Jan 2010 12:19:32 +0800 +Subject: [PATCH 3/5] st/vega: Implement st_api interface. + +--- + src/gallium/state_trackers/vega/Makefile | 1 + + src/gallium/state_trackers/vega/api_context.c | 3 + + src/gallium/state_trackers/vega/api_masks.c | 5 +- + src/gallium/state_trackers/vega/vg_api.c | 368 +++++++++++++++++++++++++ + src/gallium/state_trackers/vega/vg_api.h | 18 ++ + src/gallium/state_trackers/vega/vg_context.h | 6 + + 6 files changed, 398 insertions(+), 3 deletions(-) + create mode 100644 src/gallium/state_trackers/vega/vg_api.c + create mode 100644 src/gallium/state_trackers/vega/vg_api.h + +diff --git a/src/gallium/state_trackers/vega/Makefile b/src/gallium/state_trackers/vega/Makefile +index 037d8dc..1f0d0e5 100644 +--- a/src/gallium/state_trackers/vega/Makefile ++++ b/src/gallium/state_trackers/vega/Makefile +@@ -24,6 +24,7 @@ VG_SOURCES = \ + api_text.c \ + api_transform.c \ + vgu.c \ ++ vg_api.c \ + vg_context.c \ + vg_state.c \ + vg_tracker.c \ +diff --git a/src/gallium/state_trackers/vega/api_context.c b/src/gallium/state_trackers/vega/api_context.c +index 47db102..de3f44a 100644 +--- a/src/gallium/state_trackers/vega/api_context.c ++++ b/src/gallium/state_trackers/vega/api_context.c +@@ -26,6 +26,7 @@ + + #include "VG/openvg.h" + ++#include "vg_api.h" + #include "vg_context.h" + + #include "pipe/p_context.h" +@@ -55,6 +56,8 @@ void vgFlush(void) + + pipe = ctx->pipe; + pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL); ++ ++ st_flush_frontbuffer(); + } + + void vgFinish(void) +diff --git a/src/gallium/state_trackers/vega/api_masks.c b/src/gallium/state_trackers/vega/api_masks.c +index 9c123a4..9a308f9 100644 +--- a/src/gallium/state_trackers/vega/api_masks.c ++++ b/src/gallium/state_trackers/vega/api_masks.c +@@ -29,6 +29,7 @@ + #include "mask.h" + #include "renderer.h" + ++#include "vg_api.h" + #include "vg_context.h" + #include "pipe/p_context.h" + #include "util/u_inlines.h" +@@ -115,9 +116,7 @@ clear_with_quad(struct vg_context *st, float x0, float y0, + x1, y1); + */ + +- if (st->pipe->screen && st->pipe->screen->update_buffer) +- st->pipe->screen->update_buffer( st->pipe->screen, +- st->pipe->priv ); ++ st_validate_buffer(); + + cso_save_blend(st->cso_context); + cso_save_rasterizer(st->cso_context); +diff --git a/src/gallium/state_trackers/vega/vg_api.c b/src/gallium/state_trackers/vega/vg_api.c +new file mode 100644 +index 0000000..dcde186 +--- /dev/null ++++ b/src/gallium/state_trackers/vega/vg_api.c +@@ -0,0 +1,368 @@ ++#include "state_tracker/st_api.h" ++ ++#include "pipe/p_context.h" ++#include "pipe/p_screen.h" ++#include "util/u_memory.h" ++#include "util/u_inlines.h" ++ ++#include "vg_api.h" ++#include "vg_context.h" ++#include "vg_tracker.h" /* for st_resize_framebuffer */ ++#include "image.h" ++ ++/** ++ * Return a reference to the pipe texture of the EGLImage. ++ */ ++struct pipe_texture * ++st_manager_reference_egl_image(VGeglImageKHR eglimg) ++{ ++ struct vg_context *ctx = vg_current_context(); ++ struct st_manager *smapi = ctx->iface.st_api_private; ++ struct pipe_texture *pt = NULL, *res; ++ ++ if (!smapi) ++ return NULL; ++ ++ res = (struct pipe_texture *) smapi->lock_resource(smapi, &ctx->iface, ++ ST_MANAGER_RESOURCE_EGL_IMAGE, (void *) eglimg); ++ pipe_texture_reference(&pt, res); ++ smapi->unlock_resource(smapi, &ctx->iface, ++ ST_MANAGER_RESOURCE_EGL_IMAGE, (void *) eglimg); ++ ++ return pt; ++} ++ ++/** ++ * Flush the front buffer if the current context renders to the front buffer. ++ */ ++void ++st_flush_frontbuffer(void) ++{ ++ struct vg_context *ctx = vg_current_context(); ++ struct st_framebuffer *stfb = ctx->draw_buffer; ++ ++ if (stfb) { ++ switch (stfb->strb_att) { ++ case ST_ATTACHMENT_FRONT_LEFT: ++ case ST_ATTACHMENT_FRONT_RIGHT: ++ stfb->iface->flush_front(stfb->iface, stfb->strb_att); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++/** ++ * Re-validate the framebuffer. ++ */ ++void ++st_validate_buffer(void) ++{ ++ struct vg_context *ctx = vg_current_context(); ++ struct st_framebuffer *stfb = ctx->draw_buffer; ++ ++ if (stfb) ++ ctx->iface.notify_invalid_framebuffer(&ctx->iface, stfb->iface); ++} ++ ++ ++static void ++st_context_notify_invalid_framebuffer(struct st_context_iface *stctxi, ++ struct st_framebuffer_iface *stfbi) ++{ ++ struct vg_context *ctx = (struct vg_context *) stctxi; ++ struct pipe_screen *screen = ctx->pipe->screen; ++ struct st_framebuffer *stfb = ctx->draw_buffer; ++ struct st_renderbuffer *rb; ++ struct pipe_texture *pt; ++ ++ /* no binding surface */ ++ if (!stfb) ++ return; ++ ++ assert(stfb->iface == stfbi); ++ if (stfb->strb_att == ST_ATTACHMENT_INVALID) ++ return; ++ ++ /* validate the fb */ ++ if (!stfb->iface->validate(stfb->iface, &stfb->strb_att, 1, &pt) || !pt) ++ return; ++ ++ rb = stfb->strb; ++ if (rb->texture == pt) { ++ pipe_texture_reference(&pt, NULL); ++ return; ++ } ++ ++ /* unreference existing ones */ ++ pipe_surface_reference(&rb->surface, NULL); ++ pipe_texture_reference(&rb->texture, NULL); ++ ++ rb->texture = pt; ++ rb->surface = screen->get_tex_surface(screen, rb->texture, 0, 0, 0, ++ PIPE_BUFFER_USAGE_GPU_READ | PIPE_BUFFER_USAGE_GPU_WRITE); ++ ++ rb->width = rb->surface->width; ++ rb->height = rb->surface->height; ++ ++ st_resize_framebuffer(stfb, rb->width, rb->height); ++} ++ ++static void ++st_context_flush(struct st_context_iface *stctxi, unsigned flags, ++ struct pipe_fence_handle **fence) ++{ ++ struct vg_context *ctx = (struct vg_context *) stctxi; ++ ctx->pipe->flush(ctx->pipe, flags, fence); ++} ++ ++static void * ++st_context_lock_resource(struct st_context_iface *stctxi, ++ enum st_context_resource_type type, void *res) ++{ ++ struct vg_image *img; ++ struct pipe_texture *pt = NULL; ++ ++ if (type != ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE || ++ (VGImage) res == VG_INVALID_HANDLE) ++ return NULL; ++ ++ /* mark the image locked? */ ++ img = (struct vg_image *) res; ++ pipe_texture_reference(&pt, img->texture); ++ ++ return (void *) pt; ++} ++ ++static void ++st_context_unlock_resource(struct st_context_iface *stctxi, ++ enum st_context_resource_type type, void *res) ++{ ++ struct vg_image *img; ++ struct pipe_texture *pt; ++ ++ if (type != ST_CONTEXT_RESOURCE_OPENVG_PARENT_IMAGE || ++ (VGImage) res == VG_INVALID_HANDLE) ++ return; ++ ++ img = (struct vg_image *) res; ++ pt = img->texture; ++ pipe_texture_reference(&pt, NULL); ++} ++ ++static void ++st_context_destroy(struct st_context_iface *stctxi) ++{ ++ struct vg_context *ctx = (struct vg_context *) stctxi; ++ vg_destroy_context(ctx); ++} ++ ++static struct st_context_iface * ++st_api_create_context(struct st_api *stapi, struct st_manager *smapi, ++ struct pipe_context *pipe, ++ const struct st_visual *visual, ++ struct st_context_iface *shared_stctxi) ++{ ++ struct vg_context *shared_ctx = (struct vg_context *) shared_stctxi; ++ struct vg_context *ctx; ++ ++ ctx = vg_create_context(pipe, NULL, shared_ctx); ++ if (!ctx) ++ return NULL; ++ ++ ctx->iface.api = ST_API_OPENVG; ++ ctx->iface.destroy = st_context_destroy; ++ ctx->iface.lock_resource = st_context_lock_resource; ++ ctx->iface.unlock_resource = st_context_unlock_resource; ++ ++ ctx->iface.notify_invalid_framebuffer = ++ st_context_notify_invalid_framebuffer; ++ ctx->iface.flush = st_context_flush; ++ ++ ctx->iface.teximage = NULL; ++ ctx->iface.copy = NULL; ++ ++ ctx->iface.st_api_private = (void *) smapi; ++ ++ return &ctx->iface; ++} ++ ++static struct st_renderbuffer * ++create_renderbuffer(enum pipe_format format) ++{ ++ struct st_renderbuffer *strb; ++ ++ strb = CALLOC_STRUCT(st_renderbuffer); ++ if (strb) ++ strb->format = format; ++ ++ return strb; ++} ++ ++static void ++destroy_renderbuffer(struct st_renderbuffer *strb) ++{ ++ pipe_surface_reference(&strb->surface, NULL); ++ pipe_texture_reference(&strb->texture, NULL); ++ free(strb); ++} ++ ++/** ++ * Return the attachment of the render buffer. ++ */ ++static enum st_attachment_type ++choose_attachment(struct st_framebuffer_iface *stfbi) ++{ ++ enum st_attachment_type statt; ++ ++ statt = stfbi->visual->render_buffer; ++ if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) { ++ switch (statt) { ++ case ST_ATTACHMENT_BACK_LEFT: ++ statt = ST_ATTACHMENT_FRONT_LEFT; ++ break; ++ case ST_ATTACHMENT_BACK_RIGHT: ++ statt = ST_ATTACHMENT_FRONT_RIGHT; ++ break; ++ default: ++ break; ++ } ++ ++ if (!st_visual_have_buffers(stfbi->visual, 1 << statt)) ++ statt = ST_ATTACHMENT_INVALID; ++ } ++ ++ return statt; ++} ++ ++static boolean ++st_context_bind_framebuffers(struct st_context_iface *stctxi, ++ struct st_framebuffer_iface *stdrawi, ++ struct st_framebuffer_iface *streadi) ++{ ++ struct vg_context *ctx = (struct vg_context *) stctxi; ++ struct st_framebuffer *stfb; ++ ++ if (stdrawi != streadi) ++ return FALSE; ++ ++ if (ctx->draw_buffer) { ++ stfb = ctx->draw_buffer; ++ ++ /* free the existing fb */ ++ if (!stdrawi || ++ stfb->strb->format != stdrawi->visual->color_format || ++ stfb->dsrb->format != stdrawi->visual->depth_stencil_format) { ++ destroy_renderbuffer(stfb->strb); ++ destroy_renderbuffer(stfb->dsrb); ++ free(stfb); ++ ++ ctx->draw_buffer = NULL; ++ } ++ } ++ ++ if (!stdrawi) ++ return TRUE; ++ ++ /* create a new fb */ ++ if (!ctx->draw_buffer) { ++ stfb = CALLOC_STRUCT(st_framebuffer); ++ if (!stfb) ++ return FALSE; ++ ++ stfb->strb = create_renderbuffer(stdrawi->visual->color_format); ++ if (!stfb->strb) { ++ free(stfb); ++ return FALSE; ++ } ++ ++ stfb->dsrb = create_renderbuffer(stdrawi->visual->depth_stencil_format); ++ if (!stfb->dsrb) { ++ free(stfb->strb); ++ free(stfb); ++ return FALSE; ++ } ++ ++ stfb->width = 0; ++ stfb->height = 0; ++ ++ ctx->draw_buffer = stfb; ++ } ++ ++ ctx->draw_buffer->iface = stdrawi; ++ ctx->draw_buffer->strb_att = choose_attachment(stdrawi); ++ ++ return TRUE; ++} ++ ++static boolean ++st_api_make_current(struct st_api *stapi, struct st_context_iface *stctxi, ++ struct st_framebuffer_iface *stdrawi, ++ struct st_framebuffer_iface *streadi) ++{ ++ struct vg_context *ctx = (struct vg_context *) stctxi; ++ ++ if (stctxi) ++ st_context_bind_framebuffers(stctxi, stdrawi, streadi); ++ vg_set_current_context(ctx); ++ ++ return TRUE; ++} ++ ++static struct st_context_iface * ++st_api_get_current(struct st_api *stapi) ++{ ++ struct vg_context *ctx = vg_current_context(); ++ ++ return (ctx) ? &ctx->iface : NULL; ++} ++ ++static st_proc_t ++st_api_get_proc_address(struct st_api *stapi, const char *procname) ++{ ++ /* TODO */ ++ return (st_proc_t) NULL; ++} ++ ++static boolean ++st_api_is_visual_supported(struct st_api *stapi, ++ const struct st_visual *visual) ++{ ++ /* the impl requires a depth/stencil buffer */ ++ if (visual->depth_stencil_format == PIPE_FORMAT_NONE) ++ return FALSE; ++ ++ return TRUE; ++} ++ ++static void ++st_api_destroy(struct st_api *stapi) ++{ ++ free(stapi); ++} ++ ++static struct st_api * ++st_module_create_api(void) ++{ ++ struct st_api *stapi; ++ ++ stapi = CALLOC_STRUCT(st_api); ++ if (stapi) { ++ stapi->destroy = st_api_destroy; ++ stapi->is_visual_supported = st_api_is_visual_supported; ++ ++ stapi->create_context = st_api_create_context; ++ stapi->make_current = st_api_make_current; ++ stapi->get_current = st_api_get_current; ++ ++ stapi->get_proc_address = st_api_get_proc_address; ++ } ++ ++ return stapi; ++} ++ ++const struct st_module st_module_OpenVG = { ++ .api = ST_API_OPENVG, ++ .create_api = st_module_create_api, ++}; +diff --git a/src/gallium/state_trackers/vega/vg_api.h b/src/gallium/state_trackers/vega/vg_api.h +new file mode 100644 +index 0000000..06c65f0 +--- /dev/null ++++ b/src/gallium/state_trackers/vega/vg_api.h +@@ -0,0 +1,18 @@ ++#ifndef VG_API_H ++#define VG_API_H ++ ++#include "VG/openvg.h" ++#include "VG/vgext.h" ++ ++#include "pipe/p_state.h" ++ ++struct pipe_texture * ++st_manager_reference_egl_image(VGeglImageKHR eglimg); ++ ++void ++st_flush_frontbuffer(void); ++ ++void ++st_validate_buffer(void); ++ ++#endif /* VG_API_H */ +diff --git a/src/gallium/state_trackers/vega/vg_context.h b/src/gallium/state_trackers/vega/vg_context.h +index bc88c8d..91300ff 100644 +--- a/src/gallium/state_trackers/vega/vg_context.h ++++ b/src/gallium/state_trackers/vega/vg_context.h +@@ -33,6 +33,7 @@ + #include "pipe/p_state.h" + #include "util/u_pointer.h" + #include "util/u_math.h" ++#include "state_tracker/st_api.h" + + #include "cso_cache/cso_hash.h" + #include "cso_cache/cso_context.h" +@@ -58,6 +59,9 @@ struct st_framebuffer { + + struct pipe_texture *blend_texture; + ++ struct st_framebuffer_iface *iface; ++ enum st_attachment_type strb_att; ++ + void *privateData; + }; + +@@ -84,6 +88,8 @@ enum dirty_state { + + struct vg_context + { ++ struct st_context_iface iface; ++ + struct pipe_context *pipe; + + struct { +-- +1.6.5 + diff --git a/sample-implementation-tmp/0004-st-egl-Add-support-for-loading-st_api-modules.patch b/sample-implementation-tmp/0004-st-egl-Add-support-for-loading-st_api-modules.patch new file mode 100644 index 0000000..a8dcce3 --- /dev/null +++ b/sample-implementation-tmp/0004-st-egl-Add-support-for-loading-st_api-modules.patch @@ -0,0 +1,189 @@ +From f8f6f9c3917a72da94b36912f1cbd0303899a191 Mon Sep 17 00:00:00 2001 +From: Chia-I Wu <olvaffe@gmail.com> +Date: Thu, 14 Jan 2010 16:05:36 +0800 +Subject: [PATCH 4/5] st/egl: Add support for loading st_api modules. + +--- + src/gallium/state_trackers/egl/common/egl_st_api.c | 116 ++++++++++++++++++++ + src/gallium/state_trackers/egl/common/egl_st_api.h | 46 ++++++++ + 2 files changed, 162 insertions(+), 0 deletions(-) + create mode 100644 src/gallium/state_trackers/egl/common/egl_st_api.c + create mode 100644 src/gallium/state_trackers/egl/common/egl_st_api.h + +diff --git a/src/gallium/state_trackers/egl/common/egl_st_api.c b/src/gallium/state_trackers/egl/common/egl_st_api.c +new file mode 100644 +index 0000000..bfcc49e +--- /dev/null ++++ b/src/gallium/state_trackers/egl/common/egl_st_api.c +@@ -0,0 +1,116 @@ ++#include "util/u_memory.h" ++#include "util/u_dl.h" ++#include "eglimage.h" ++ ++#include "egl_st_api.h" ++ ++struct egl_g3d_st_manager { ++ struct st_manager base; ++ _EGLDisplay *display; ++}; ++ ++static INLINE struct egl_g3d_st_manager * ++egl_g3d_st_manager(struct st_manager *smapi) ++{ ++ return (struct egl_g3d_st_manager *) smapi; ++} ++ ++static void * ++egl_g3d_st_manager_lock_resource(struct st_manager *smapi, ++ struct st_context_iface *stctxi, ++ enum st_manager_resource_type type, ++ void *res) ++{ ++ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); ++ void *ret; ++ ++ switch (type) { ++ case ST_MANAGER_RESOURCE_EGL_IMAGE: ++ { ++ EGLImageKHR handle = (EGLImageKHR) res; ++ _EGLImage *img = _eglLookupImage(handle, gsmapi->display); ++ ++ /* TODO retrieve the pipe texture of the image */ ++ (void) img; ++ ++ ret = NULL; ++ } ++ break; ++ default: ++ ret = NULL; ++ break; ++ } ++ ++ return ret; ++} ++ ++static void ++egl_g3d_st_manager_unlock_resource(struct st_manager *smapi, ++ struct st_context_iface *stctxi, ++ enum st_manager_resource_type type, ++ void *res) ++{ ++} ++ ++struct st_manager * ++egl_g3d_create_st_manager(_EGLDisplay *dpy) ++{ ++ struct egl_g3d_st_manager *gsmapi; ++ ++ gsmapi = CALLOC_STRUCT(egl_g3d_st_manager); ++ if (gsmapi) { ++ gsmapi->display = dpy; ++ ++ gsmapi->base.lock_resource = egl_g3d_st_manager_lock_resource; ++ gsmapi->base.unlock_resource = egl_g3d_st_manager_unlock_resource; ++ } ++ ++ return &gsmapi->base;; ++} ++ ++void ++egl_g3d_destroy_st_manager(struct st_manager *smapi) ++{ ++ struct egl_g3d_st_manager *gsmapi = egl_g3d_st_manager(smapi); ++ free(gsmapi); ++} ++ ++struct st_api * ++egl_g3d_create_st_api(enum st_api_type api) ++{ ++ const char *stmod_name; ++ struct util_dl_library *lib; ++ const struct st_module *mod; ++ ++ switch (api) { ++ case ST_API_OPENGL: ++ stmod_name = ST_MODULE_OPENGL_SYMBOL; ++ break; ++ case ST_API_OPENGL_ES1: ++ stmod_name = ST_MODULE_OPENGL_ES1_SYMBOL; ++ break; ++ case ST_API_OPENGL_ES2: ++ stmod_name = ST_MODULE_OPENGL_ES2_SYMBOL; ++ break; ++ case ST_API_OPENVG: ++ stmod_name = ST_MODULE_OPENVG_SYMBOL; ++ break; ++ default: ++ stmod_name = NULL; ++ break; ++ } ++ if (!stmod_name) ++ return NULL; ++ ++ mod = NULL; ++ lib = util_dl_open(NULL); ++ if (lib) { ++ mod = (const struct st_module *) ++ util_dl_get_proc_address(lib, stmod_name); ++ util_dl_close(lib); ++ } ++ if (!mod || mod->api != api) ++ return NULL; ++ ++ return mod->create_api(); ++} +diff --git a/src/gallium/state_trackers/egl/common/egl_st_api.h b/src/gallium/state_trackers/egl/common/egl_st_api.h +new file mode 100644 +index 0000000..f39f318 +--- /dev/null ++++ b/src/gallium/state_trackers/egl/common/egl_st_api.h +@@ -0,0 +1,46 @@ ++#ifndef _EGL_ST_API_H_ ++#define _EGL_ST_API_H_ ++ ++#include "pipe/p_compiler.h" ++#include "state_tracker/st_api.h" ++#include "egltypedefs.h" ++ ++struct st_manager * ++egl_g3d_create_st_manager(_EGLDisplay *dpy); ++ ++void ++egl_g3d_destroy_st_manager(struct st_manager *smapi); ++ ++struct st_api * ++egl_g3d_create_st_api(enum st_api_type api); ++ ++/** ++ * Return the EGL_<api>_BIT of the st api. ++ */ ++static INLINE int ++egl_g3d_st_api_bit(enum st_api_type api) ++{ ++ int bit; ++ ++ switch (api) { ++ case ST_API_OPENGL: ++ bit = EGL_OPENGL_BIT; ++ break; ++ case ST_API_OPENGL_ES1: ++ bit = EGL_OPENGL_ES_BIT; ++ break; ++ case ST_API_OPENGL_ES2: ++ bit = EGL_OPENGL_ES2_BIT; ++ break; ++ case ST_API_OPENVG: ++ bit = EGL_OPENVG_BIT; ++ break; ++ default: ++ bit = 0; ++ break; ++ } ++ ++ return bit; ++} ++ ++#endif /* _EGL_ST_API_H_ */ +-- +1.6.5 + diff --git a/sample-implementation-tmp/0005-st-egl-Use-st_api.h-instead-of-st_public.h.patch b/sample-implementation-tmp/0005-st-egl-Use-st_api.h-instead-of-st_public.h.patch new file mode 100644 index 0000000..f5dbec7 --- /dev/null +++ b/sample-implementation-tmp/0005-st-egl-Use-st_api.h-instead-of-st_public.h.patch @@ -0,0 +1,1103 @@ +From 61f5bc139286416251a1e42fad239b53feaa654c Mon Sep 17 00:00:00 2001 +From: Chia-I Wu <olvaffe@gmail.com> +Date: Mon, 25 Jan 2010 22:18:29 +0800 +Subject: [PATCH 5/5] st/egl: Use st_api.h instead of st_public.h. + +--- + src/gallium/state_trackers/egl/common/egl_g3d.c | 539 ++++++++------------ + src/gallium/state_trackers/egl/common/egl_g3d.h | 19 +- + src/gallium/state_trackers/egl/common/egl_st.c | 131 ----- + src/gallium/state_trackers/egl/common/egl_st.h | 73 --- + .../state_trackers/egl/common/st_public_tmp.h | 20 - + 5 files changed, 233 insertions(+), 549 deletions(-) + delete mode 100644 src/gallium/state_trackers/egl/common/egl_st.c + delete mode 100644 src/gallium/state_trackers/egl/common/egl_st.h + delete mode 100644 src/gallium/state_trackers/egl/common/st_public_tmp.h + +diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.c b/src/gallium/state_trackers/egl/common/egl_g3d.c +index 7021617..8c51e99 100644 +--- a/src/gallium/state_trackers/egl/common/egl_g3d.c ++++ b/src/gallium/state_trackers/egl/common/egl_g3d.c +@@ -36,233 +36,26 @@ + + #include "native.h" + #include "egl_g3d.h" +-#include "egl_st.h" +- +-/** +- * Validate the draw/read surfaces of the context. +- */ +-static void +-egl_g3d_validate_context(_EGLDisplay *dpy, _EGLContext *ctx) +-{ +- struct egl_g3d_display *gdpy = egl_g3d_display(dpy); +- struct pipe_screen *screen = gdpy->native->screen; +- struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- const uint st_att_map[NUM_NATIVE_ATTACHMENTS] = { +- ST_SURFACE_FRONT_LEFT, +- ST_SURFACE_BACK_LEFT, +- ST_SURFACE_FRONT_RIGHT, +- ST_SURFACE_BACK_RIGHT, +- }; +- EGLint num_surfaces, s; +- +- /* validate draw and/or read buffers */ +- num_surfaces = (gctx->base.ReadSurface == gctx->base.DrawSurface) ? 1 : 2; +- for (s = 0; s < num_surfaces; s++) { +- struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; +- struct egl_g3d_surface *gsurf; +- struct egl_g3d_buffer *gbuf; +- EGLint att; +- +- if (s == 0) { +- gsurf = egl_g3d_surface(gctx->base.DrawSurface); +- gbuf = &gctx->draw; +- } +- else { +- gsurf = egl_g3d_surface(gctx->base.ReadSurface); +- gbuf = &gctx->read; +- } +- +- if (!gctx->force_validate) { +- unsigned int seq_num; +- +- gsurf->native->validate(gsurf->native, gbuf->attachment_mask, +- &seq_num, NULL, NULL, NULL); +- /* skip validation */ +- if (gsurf->sequence_number == seq_num) +- continue; +- } +- +- pipe_surface_reference(&gsurf->render_surface, NULL); +- memset(textures, 0, sizeof(textures)); +- +- gsurf->native->validate(gsurf->native, gbuf->attachment_mask, +- &gsurf->sequence_number, textures, +- &gsurf->base.Width, &gsurf->base.Height); +- for (att = 0; att < NUM_NATIVE_ATTACHMENTS; att++) { +- struct pipe_texture *pt = textures[att]; +- struct pipe_surface *ps; +- +- if (native_attachment_mask_test(gbuf->attachment_mask, att) && pt) { +- ps = screen->get_tex_surface(screen, pt, 0, 0, 0, +- PIPE_BUFFER_USAGE_GPU_READ | +- PIPE_BUFFER_USAGE_GPU_WRITE); +- gctx->stapi->st_set_framebuffer_surface(gbuf->st_fb, +- st_att_map[att], ps); +- +- if (gsurf->render_att == att) +- pipe_surface_reference(&gsurf->render_surface, ps); +- +- pipe_surface_reference(&ps, NULL); +- pipe_texture_reference(&pt, NULL); +- } +- } +- +- gctx->stapi->st_resize_framebuffer(gbuf->st_fb, +- gsurf->base.Width, gsurf->base.Height); +- } +- +- gctx->force_validate = EGL_FALSE; +- +-} +- +-/** +- * Create a st_framebuffer. +- */ +-static struct st_framebuffer * +-create_framebuffer(_EGLContext *ctx, _EGLSurface *surf) +-{ +- struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); +- struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); +- +- return gctx->stapi->st_create_framebuffer(&gconf->native->mode, +- gconf->native->color_format, gconf->native->depth_format, +- gconf->native->stencil_format, +- gsurf->base.Width, gsurf->base.Height, &gsurf->base); +-} +- +-/** +- * Update the attachments of draw/read surfaces. +- */ +-static void +-egl_g3d_route_context(_EGLDisplay *dpy, _EGLContext *ctx) +-{ +- struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- EGLint s; +- +- /* route draw and read buffers' attachments */ +- for (s = 0; s < 2; s++) { +- struct egl_g3d_surface *gsurf; +- struct egl_g3d_buffer *gbuf; +- +- if (s == 0) { +- gsurf = egl_g3d_surface(gctx->base.DrawSurface); +- gbuf = &gctx->draw; +- } +- else { +- gsurf = egl_g3d_surface(gctx->base.ReadSurface); +- gbuf = &gctx->read; +- } +- +- gbuf->attachment_mask = (1 << gsurf->render_att); +- +- /* FIXME OpenGL defaults to draw the front or back buffer when the +- * context is single-buffered or double-buffered respectively. In EGL, +- * however, the buffer to be drawn is determined by the surface, instead +- * of the context. As a result, rendering to a pixmap surface with a +- * double-buffered context does not work as expected. +- * +- * gctx->stapi->st_draw_front_buffer(gctx->st_ctx, natt == +- * NATIVE_ATTACHMENT_FRONT_LEFT); +- */ +- +- /* +- * FIXME If the back buffer is asked for here, and the front buffer is +- * later needed by the client API (e.g. glDrawBuffer is called to draw +- * the front buffer), it will create a new pipe texture and draw there. +- * One fix is to ask for both buffers here, but it would be a waste if +- * the front buffer is never used. A better fix is to add a callback to +- * the pipe screen with context private (just like flush_frontbuffer). +- */ +- } +-} +- +-/** +- * Reallocate the context's framebuffers after draw/read surfaces change. +- */ +-static EGLBoolean +-egl_g3d_realloc_context(_EGLDisplay *dpy, _EGLContext *ctx) +-{ +- struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- struct egl_g3d_surface *gdraw = egl_g3d_surface(gctx->base.DrawSurface); +- struct egl_g3d_surface *gread = egl_g3d_surface(gctx->base.ReadSurface); +- +- /* unreference the old framebuffers */ +- if (gctx->draw.st_fb) { +- EGLBoolean is_equal = (gctx->draw.st_fb == gctx->read.st_fb); +- void *priv; +- +- priv = gctx->stapi->st_framebuffer_private(gctx->draw.st_fb); +- if (!gdraw || priv != (void *) &gdraw->base) { +- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); +- gctx->draw.st_fb = NULL; +- gctx->draw.attachment_mask = 0x0; +- } +- +- if (is_equal) { +- gctx->read.st_fb = NULL; +- gctx->draw.attachment_mask = 0x0; +- } +- else { +- priv = gctx->stapi->st_framebuffer_private(gctx->read.st_fb); +- if (!gread || priv != (void *) &gread->base) { +- gctx->stapi->st_unreference_framebuffer(gctx->read.st_fb); +- gctx->read.st_fb = NULL; +- gctx->draw.attachment_mask = 0x0; +- } +- } +- } +- +- if (!gdraw) +- return EGL_TRUE; +- +- /* create the draw fb */ +- if (!gctx->draw.st_fb) { +- gctx->draw.st_fb = create_framebuffer(&gctx->base, &gdraw->base); +- if (!gctx->draw.st_fb) +- return EGL_FALSE; +- } +- +- /* create the read fb */ +- if (!gctx->read.st_fb) { +- if (gread != gdraw) { +- gctx->read.st_fb = create_framebuffer(&gctx->base, &gread->base); +- if (!gctx->read.st_fb) { +- gctx->stapi->st_unreference_framebuffer(gctx->draw.st_fb); +- gctx->draw.st_fb = NULL; +- return EGL_FALSE; +- } +- } +- else { +- /* there is no st_reference_framebuffer... */ +- gctx->read.st_fb = gctx->draw.st_fb; +- } +- } +- +- egl_g3d_route_context(dpy, &gctx->base); +- gctx->force_validate = EGL_TRUE; +- +- return EGL_TRUE; +-} ++#include "egl_st_api.h" + + /** + * Return the state tracker for the given context. + */ +-static const struct egl_g3d_st * ++static struct st_api * + egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) + { + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); +- const struct egl_g3d_st *stapi; ++ struct st_api *stapi; + EGLint idx = -1; + + switch (ctx->ClientAPI) { + case EGL_OPENGL_ES_API: + switch (ctx->ClientVersion) { + case 1: +- idx = EGL_G3D_ST_OPENGL_ES; ++ idx = ST_API_OPENGL_ES1; + break; + case 2: +- idx = EGL_G3D_ST_OPENGL_ES2; ++ idx = ST_API_OPENGL_ES2; + break; + default: + _eglLog(_EGL_WARNING, "unknown client version %d", +@@ -271,10 +64,10 @@ egl_g3d_choose_st(_EGLDriver *drv, _EGLContext *ctx) + } + break; + case EGL_OPENVG_API: +- idx = EGL_G3D_ST_OPENVG; ++ idx = ST_API_OPENVG; + break; + case EGL_OPENGL_API: +- idx = EGL_G3D_ST_OPENGL; ++ idx = ST_API_OPENGL; + break; + default: + _eglLog(_EGL_WARNING, "unknown client API 0x%04x", ctx->ClientAPI); +@@ -298,10 +91,10 @@ egl_g3d_init_st(_EGLDriver *drv) + if (gdrv->api_mask) + return; + +- for (i = 0; i < NUM_EGL_G3D_STS; i++) { +- gdrv->stapis[i] = egl_g3d_get_st(i); ++ for (i = 0; i < ST_API_COUNT; i++) { ++ gdrv->stapis[i] = egl_g3d_create_st_api(i); + if (gdrv->stapis[i]) +- gdrv->api_mask |= gdrv->stapis[i]->api_bit; ++ gdrv->api_mask |= egl_g3d_st_api_bit(i); + } + + if (gdrv->api_mask) +@@ -507,36 +300,6 @@ egl_g3d_add_configs(_EGLDriver *drv, _EGLDisplay *dpy, EGLint id) + return id; + } + +-/** +- * Flush the front buffer of the context's draw surface. +- */ +-static void +-egl_g3d_flush_frontbuffer(struct pipe_screen *screen, +- struct pipe_surface *surf, void *context_private) +-{ +- struct egl_g3d_context *gctx = egl_g3d_context(context_private); +- struct egl_g3d_surface *gsurf = egl_g3d_surface(gctx->base.DrawSurface); +- +- if (gsurf) +- gsurf->native->flush_frontbuffer(gsurf->native); +-} +- +-/** +- * Re-validate the context. +- */ +-static void +-egl_g3d_update_buffer(struct pipe_screen *screen, void *context_private) +-{ +- struct egl_g3d_context *gctx = egl_g3d_context(context_private); +- +- /** +- * It is likely that the surface has changed when this function is called. +- * Set force_validate to skip an unnecessary check. +- */ +- gctx->force_validate = EGL_TRUE; +- egl_g3d_validate_context(gctx->base.Resource.Display, &gctx->base); +-} +- + static EGLBoolean + egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) + { +@@ -555,6 +318,9 @@ egl_g3d_terminate(_EGLDriver *drv, _EGLDisplay *dpy) + free(dpy->Screens); + } + ++ if (gdpy->smapi) ++ egl_g3d_destroy_st_manager(gdpy->smapi); ++ + if (gdpy->native) + gdpy->native->destroy(gdpy->native); + +@@ -587,9 +353,6 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, + goto fail; + } + +- gdpy->native->screen->flush_frontbuffer = egl_g3d_flush_frontbuffer; +- gdpy->native->screen->update_buffer = egl_g3d_update_buffer; +- + egl_g3d_init_st(&gdrv->base); + dpy->ClientAPIsMask = gdrv->api_mask; + +@@ -598,6 +361,13 @@ egl_g3d_initialize(_EGLDriver *drv, _EGLDisplay *dpy, + goto fail; + } + ++ gdpy->smapi = egl_g3d_create_st_manager(dpy); ++ if (!gdpy->smapi) { ++ _eglError(EGL_NOT_INITIALIZED, ++ "eglInitialize(failed to create st manager)"); ++ goto fail; ++ } ++ + #ifdef EGL_MESA_screen_surface + /* enable MESA_screen_surface */ + if (gdpy->native->modeset) { +@@ -652,9 +422,9 @@ egl_g3d_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, + return NULL; + } + +- gctx->st_ctx = gctx->stapi->st_create_context(gctx->pipe, mode, +- (gshare) ? gshare->st_ctx : NULL); +- if (!gctx->st_ctx) { ++ gctx->stctxi = gctx->stapi->create_context(gctx->stapi, gdpy->smapi, ++ gctx->pipe, NULL, (gshare) ? gshare->stctxi : NULL); ++ if (!gctx->stctxi) { + gctx->pipe->destroy(gctx->pipe); + free(gctx); + return NULL; +@@ -675,9 +445,8 @@ destroy_context(_EGLDisplay *dpy, _EGLContext *ctx) + if (!dpy->Initialized) + _eglLog(_EGL_FATAL, "destroy a context with an unitialized display"); + +- egl_g3d_realloc_context(dpy, &gctx->base); +- /* it will destroy the associated pipe context */ +- gctx->stapi->st_destroy_context(gctx->st_ctx); ++ /* it will destroy the pipe context */ ++ gctx->stctxi->destroy(gctx->stctxi); + + free(gctx); + } +@@ -690,6 +459,140 @@ egl_g3d_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) + return EGL_TRUE; + } + ++static boolean ++egl_g3d_framebuffer_flush_front(struct st_framebuffer_iface *stfbi, ++ enum st_attachment_type statt) ++{ ++ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; ++ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); ++ ++ return gsurf->native->flush_frontbuffer(gsurf->native); ++} ++ ++static boolean ++egl_g3d_framebuffer_validate(struct st_framebuffer_iface *stfbi, ++ const enum st_attachment_type *statts, ++ unsigned count, ++ struct pipe_texture **out) ++{ ++ _EGLSurface *surf = (_EGLSurface *) stfbi->st_manager_private; ++ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); ++ struct pipe_texture *textures[NUM_NATIVE_ATTACHMENTS]; ++ uint attachment_mask = 0; ++ unsigned i; ++ ++ for (i = 0; i < count; i++) { ++ int natt; ++ ++ switch (statts[i]) { ++ case ST_ATTACHMENT_FRONT_LEFT: ++ natt = NATIVE_ATTACHMENT_FRONT_LEFT; ++ break; ++ case ST_ATTACHMENT_BACK_LEFT: ++ natt = NATIVE_ATTACHMENT_BACK_LEFT; ++ break; ++ case ST_ATTACHMENT_FRONT_RIGHT: ++ natt = NATIVE_ATTACHMENT_FRONT_RIGHT; ++ break; ++ case ST_ATTACHMENT_BACK_RIGHT: ++ natt = NATIVE_ATTACHMENT_BACK_RIGHT; ++ default: ++ natt = -1; ++ break; ++ } ++ ++ if (natt >= 0) ++ attachment_mask |= 1 << natt; ++ } ++ ++ if (!gsurf->native->validate(gsurf->native, attachment_mask, ++ &gsurf->sequence_number, textures, &gsurf->base.Width, ++ &gsurf->base.Height)) ++ return FALSE; ++ ++ for (i = 0; i < count; i++) { ++ struct pipe_texture *tex; ++ int natt; ++ ++ switch (statts[i]) { ++ case ST_ATTACHMENT_FRONT_LEFT: ++ natt = NATIVE_ATTACHMENT_FRONT_LEFT; ++ break; ++ case ST_ATTACHMENT_BACK_LEFT: ++ natt = NATIVE_ATTACHMENT_BACK_LEFT; ++ break; ++ case ST_ATTACHMENT_FRONT_RIGHT: ++ natt = NATIVE_ATTACHMENT_FRONT_RIGHT; ++ break; ++ case ST_ATTACHMENT_BACK_RIGHT: ++ natt = NATIVE_ATTACHMENT_BACK_RIGHT; ++ break; ++ default: ++ natt = -1; ++ break; ++ } ++ ++ if (natt >= 0) { ++ tex = textures[natt]; ++ ++ if (attachment_mask & (1 << natt)) { ++ /* transfer the ownership to the caller */ ++ out[i] = tex; ++ attachment_mask &= ~(1 << natt); ++ } ++ else { ++ /* the attachment is listed more than once */ ++ pipe_texture_reference(&out[i], tex); ++ } ++ } ++ } ++ ++ return TRUE; ++} ++ ++static EGLBoolean ++init_surface_framebuffer(_EGLSurface *surf, _EGLConfig *conf) ++{ ++ struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); ++ struct egl_g3d_config *gconf = egl_g3d_config(conf); ++ struct st_framebuffer_iface *stfbi; ++ unsigned buffer_mask; ++ ++ stfbi = CALLOC_STRUCT(st_framebuffer_iface); ++ if (!stfbi) ++ return EGL_FALSE; ++ ++ buffer_mask = ST_ATTACHMENT_FRONT_LEFT_MASK; ++ if (gconf->native->mode.doubleBufferMode) ++ buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK; ++ if (gconf->native->mode.stereoMode) { ++ buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK; ++ if (gconf->native->mode.doubleBufferMode) ++ buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK; ++ } ++ ++ gsurf->stvis.buffer_mask = buffer_mask; ++ gsurf->stvis.color_format = gconf->native->color_format; ++ gsurf->stvis.depth_stencil_format = gconf->native->depth_format; ++ gsurf->stvis.accum_format = PIPE_FORMAT_NONE; ++ gsurf->stvis.samples = 0; ++ ++ if (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || ++ !(buffer_mask & ST_ATTACHMENT_BACK_LEFT)) ++ gsurf->stvis.render_buffer = ST_ATTACHMENT_FRONT_LEFT; ++ else ++ gsurf->stvis.render_buffer = ST_ATTACHMENT_BACK_LEFT; ++ ++ stfbi->visual = &gsurf->stvis; ++ stfbi->flush_front = egl_g3d_framebuffer_flush_front; ++ stfbi->validate = egl_g3d_framebuffer_validate; ++ stfbi->st_manager_private = (void *) &gsurf->base; ++ ++ gsurf->stfbi = stfbi; ++ ++ return EGL_TRUE; ++} ++ + static EGLBoolean + init_surface_geometry(_EGLSurface *surf) + { +@@ -727,16 +630,13 @@ egl_g3d_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, + return NULL; + } + +- if (!init_surface_geometry(&gsurf->base)) { ++ if (!init_surface_geometry(&gsurf->base) || ++ !init_surface_framebuffer(&gsurf->base, &gconf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + +- gsurf->render_att = (gsurf->base.RenderBuffer == EGL_SINGLE_BUFFER || +- !gconf->native->mode.doubleBufferMode) ? +- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; +- + return &gsurf->base; + } + +@@ -767,14 +667,13 @@ egl_g3d_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, + return NULL; + } + +- if (!init_surface_geometry(&gsurf->base)) { ++ if (!init_surface_geometry(&gsurf->base) || ++ !init_surface_framebuffer(&gsurf->base, &gconf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + +- gsurf->render_att = NATIVE_ATTACHMENT_FRONT_LEFT; +- + return &gsurf->base; + } + +@@ -805,15 +704,13 @@ egl_g3d_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, + return NULL; + } + +- if (!init_surface_geometry(&gsurf->base)) { ++ if (!init_surface_geometry(&gsurf->base) || ++ !init_surface_framebuffer(&gsurf->base, &gconf->base)) { + gsurf->native->destroy(gsurf->native); + free(gsurf); + return NULL; + } + +- gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? +- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; +- + return &gsurf->base; + } + +@@ -831,6 +728,7 @@ destroy_surface(_EGLDisplay *dpy, _EGLSurface *surf) + + pipe_surface_reference(&gsurf->render_surface, NULL); + gsurf->native->destroy(gsurf->native); ++ free(gsurf->stfbi); + free(gsurf); + } + +@@ -848,6 +746,7 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, + { + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + struct egl_g3d_surface *gdraw = egl_g3d_surface(draw); ++ struct egl_g3d_surface *gread = egl_g3d_surface(read); + struct egl_g3d_context *old_gctx; + EGLBoolean ok = EGL_TRUE; + +@@ -858,34 +757,29 @@ egl_g3d_make_current(_EGLDriver *drv, _EGLDisplay *dpy, + + if (old_gctx) { + /* flush old context */ +- old_gctx->stapi->st_flush(old_gctx->st_ctx, ++ old_gctx->stctxi->flush(old_gctx->stctxi, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); +- +- /* +- * The old context is no longer current, and egl_g3d_realloc_context() +- * should be called to destroy the framebuffers. However, it is possible +- * that it will be made current again with the same draw/read surfaces. +- * It might be better to keep it around. +- */ + } + + if (gctx) { +- ok = egl_g3d_realloc_context(dpy, &gctx->base); ++ ok = gctx->stapi->make_current(gctx->stapi, gctx->stctxi, ++ (gdraw) ? gdraw->stfbi : NULL, (gread) ? gread->stfbi : NULL); + if (ok) { +- ok = gctx->stapi->st_make_current(gctx->st_ctx, +- gctx->draw.st_fb, gctx->read.st_fb); +- if (ok) { +- egl_g3d_validate_context(dpy, &gctx->base); +- if (gdraw->base.Type == EGL_WINDOW_BIT) { +- gctx->base.WindowRenderBuffer = +- (gdraw->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ? +- EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; +- } ++ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gdraw->stfbi); ++ if (gread != gdraw) { ++ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, ++ gread->stfbi); ++ } ++ ++ if (gdraw->base.Type == EGL_WINDOW_BIT) { ++ gctx->base.WindowRenderBuffer = ++ (gdraw->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) ? ++ EGL_SINGLE_BUFFER : EGL_BACK_BUFFER; + } + } + } + else if (old_gctx) { +- ok = old_gctx->stapi->st_make_current(NULL, NULL, NULL); ++ ok = old_gctx->stapi->make_current(old_gctx->stapi, NULL, NULL, NULL); + old_gctx->base.WindowRenderBuffer = EGL_NONE; + } + +@@ -912,15 +806,17 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) + return EGL_TRUE; + + /* or when the surface is single-buffered */ +- if (gsurf->render_att == NATIVE_ATTACHMENT_FRONT_LEFT) ++ if (gsurf->stvis.render_buffer == ST_ATTACHMENT_FRONT_LEFT) + return EGL_TRUE; + + if (ctx && ctx->DrawSurface == surf) + gctx = egl_g3d_context(ctx); + + /* flush if the surface is current */ +- if (gctx) +- gctx->stapi->st_notify_swapbuffers(gctx->draw.st_fb); ++ if (gctx) { ++ gctx->stctxi->flush(gctx->stctxi, ++ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); ++ } + + /* + * We drew on the back buffer, unless there was no back buffer. +@@ -933,11 +829,9 @@ egl_g3d_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf) + if (gctx) { + struct egl_g3d_config *gconf = egl_g3d_config(gsurf->base.Config); + +- /* force validation if the swap method is not copy */ +- if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) { +- gctx->force_validate = EGL_TRUE; +- egl_g3d_validate_context(dpy, &gctx->base); +- } ++ /* validate if the swap method is not copy */ ++ if (gconf->native->mode.swapMethod != GLX_SWAP_COPY_OML) ++ gctx->stctxi->notify_invalid_framebuffer(gctx->stctxi, gsurf->stfbi); + } + + return EGL_TRUE; +@@ -1011,7 +905,7 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + /* flush if the surface is current */ + if (ctx && ctx->DrawSurface == &gsurf->base) { + struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- gctx->stapi->st_flush(gctx->st_ctx, ++ gctx->stctxi->flush(gctx->stctxi, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + +@@ -1041,8 +935,16 @@ egl_g3d_copy_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, + static EGLBoolean + egl_g3d_wait_client(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx) + { ++ struct egl_g3d_display *gdpy = egl_g3d_display(dpy); + struct egl_g3d_context *gctx = egl_g3d_context(ctx); +- gctx->stapi->st_finish(gctx->st_ctx); ++ struct pipe_screen *screen = gdpy->native->screen; ++ struct pipe_fence_handle *fence = NULL; ++ ++ gctx->stctxi->flush(gctx->stctxi, ++ PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, &fence); ++ screen->fence_finish(screen, fence, 0); ++ screen->fence_reference(screen, &fence, NULL); ++ + return EGL_TRUE; + } + +@@ -1072,10 +974,10 @@ egl_g3d_get_proc_address(_EGLDriver *drv, const char *procname) + /* in case this is called before a display is initialized */ + egl_g3d_init_st(&gdrv->base); + +- for (i = 0; i < NUM_EGL_G3D_STS; i++) { +- const struct egl_g3d_st *stapi = gdrv->stapis[i]; ++ for (i = 0; i < ST_API_COUNT; i++) { ++ struct st_api *stapi = gdrv->stapis[i]; + if (stapi) { +- proc = (_EGLProc) stapi->st_get_proc_address(procname); ++ proc = (_EGLProc) stapi->get_proc_address(stapi, procname); + if (proc) + return proc; + } +@@ -1091,8 +993,8 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + struct egl_g3d_surface *gsurf = egl_g3d_surface(surf); + _EGLContext *es1 = _eglGetAPIContext(EGL_OPENGL_ES_API); + struct egl_g3d_context *gctx; +- enum pipe_format target_format; +- int target; ++ enum pipe_format internal_format; ++ enum st_texture_type target; + + if (!gsurf || gsurf->base.Type != EGL_PBUFFER_BIT) + return _eglError(EGL_BAD_SURFACE, "eglBindTexImage"); +@@ -1103,10 +1005,10 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + + switch (gsurf->base.TextureFormat) { + case EGL_TEXTURE_RGB: +- target_format = PIPE_FORMAT_R8G8B8_UNORM; ++ internal_format = PIPE_FORMAT_R8G8B8_UNORM; + break; + case EGL_TEXTURE_RGBA: +- target_format = PIPE_FORMAT_A8R8G8B8_UNORM; ++ internal_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + default: + return _eglError(EGL_BAD_MATCH, "eglBindTexImage"); +@@ -1128,15 +1030,18 @@ egl_g3d_bind_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + /* flush properly if the surface is bound */ + if (gsurf->base.CurrentContext) { + gctx = egl_g3d_context(gsurf->base.CurrentContext); +- gctx->stapi->st_flush(gctx->st_ctx, ++ gctx->stctxi->flush(gctx->stctxi, + PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL); + } + + gctx = egl_g3d_context(es1); +- gctx->stapi->st_bind_texture_surface(gsurf->render_surface, +- target, gsurf->base.MipmapLevel, target_format); +- +- gsurf->base.BoundToTexture = EGL_TRUE; ++ if (gctx->stctxi->teximage) { ++ if (!gctx->stctxi->teximage(gctx->stctxi, target, ++ gsurf->base.MipmapLevel, internal_format, ++ gsurf->render_surface->texture, gsurf->base.MipmapTexture)) ++ return EGL_FALSE; ++ gsurf->base.BoundToTexture = EGL_TRUE; ++ } + + return EGL_TRUE; + } +@@ -1158,9 +1063,10 @@ egl_g3d_release_tex_image(_EGLDriver *drv, _EGLDisplay *dpy, + struct egl_g3d_context *gctx = egl_g3d_context(ctx); + + /* what if the context the surface binds to is no longer current? */ +- if (gctx) +- gctx->stapi->st_unbind_texture_surface(gsurf->render_surface, +- ST_TEXTURE_2D, gsurf->base.MipmapLevel); ++ if (gctx) { ++ gctx->stctxi->teximage(gctx->stctxi, ST_TEXTURE_2D, ++ gsurf->base.MipmapLevel, PIPE_FORMAT_NONE, NULL, FALSE); ++ } + } + + gsurf->base.BoundToTexture = EGL_FALSE; +@@ -1198,9 +1104,6 @@ egl_g3d_create_screen_surface(_EGLDriver *drv, _EGLDisplay *dpy, + return NULL; + } + +- gsurf->render_att = (!gconf->native->mode.doubleBufferMode) ? +- NATIVE_ATTACHMENT_FRONT_LEFT : NATIVE_ATTACHMENT_BACK_LEFT; +- + return &gsurf->base; + } + +@@ -1294,6 +1197,12 @@ static void + egl_g3d_unload(_EGLDriver *drv) + { + struct egl_g3d_driver *gdrv = egl_g3d_driver(drv); ++ EGLint i; ++ ++ for (i = 0; i < ST_API_COUNT; i++) { ++ if (gdrv->stapis[i]) ++ gdrv->stapis[i]->destroy(gdrv->stapis[i]); ++ } + + egl_g3d_destroy_probe(drv, NULL); + free(gdrv); +diff --git a/src/gallium/state_trackers/egl/common/egl_g3d.h b/src/gallium/state_trackers/egl/common/egl_g3d.h +index 3dae8c4..e2b73bb 100644 +--- a/src/gallium/state_trackers/egl/common/egl_g3d.h ++++ b/src/gallium/state_trackers/egl/common/egl_g3d.h +@@ -38,11 +38,11 @@ + #include "eglmode.h" + + #include "native.h" +-#include "egl_st.h" ++#include "egl_st_api.h" + + struct egl_g3d_driver { + _EGLDriver base; +- const struct egl_g3d_st *stapis[NUM_EGL_G3D_STS]; ++ struct st_api *stapis[ST_API_COUNT]; + EGLint api_mask; + + EGLint probe_key; +@@ -50,28 +50,27 @@ struct egl_g3d_driver { + + struct egl_g3d_display { + struct native_display *native; +-}; + +-struct egl_g3d_buffer { +- struct st_framebuffer *st_fb; +- uint attachment_mask; ++ struct st_manager *smapi; + }; + + struct egl_g3d_context { + _EGLContext base; + +- const struct egl_g3d_st *stapi; ++ struct st_api *stapi; + struct pipe_context *pipe; + +- struct st_context *st_ctx; ++ struct st_context_iface *stctxi; + EGLBoolean force_validate; +- struct egl_g3d_buffer draw, read; + }; + + struct egl_g3d_surface { + _EGLSurface base; ++ ++ struct st_visual stvis; ++ struct st_framebuffer_iface *stfbi; ++ + struct native_surface *native; +- enum native_attachment render_att; + struct pipe_surface *render_surface; + unsigned int sequence_number; + }; +diff --git a/src/gallium/state_trackers/egl/common/egl_st.c b/src/gallium/state_trackers/egl/common/egl_st.c +deleted file mode 100644 +index a88ff91..0000000 +--- a/src/gallium/state_trackers/egl/common/egl_st.c ++++ /dev/null +@@ -1,131 +0,0 @@ +-/* +- * Mesa 3-D graphics library +- * Version: 7.8 +- * +- * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> +- * +- * 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 +- * BRIAN PAUL 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. +- */ +- +-#include <dlfcn.h> +-#include "pipe/p_compiler.h" +-#include "util/u_memory.h" +-#include "egllog.h" +-#include "EGL/egl.h" /* for EGL_api_BIT */ +- +-#include "egl_st.h" +- +-#ifndef HAVE_DLADDR +-#define HAVE_DLADDR 1 +-#endif +- +-#if HAVE_DLADDR +- +-static const char * +-egl_g3d_st_names[] = { +-#define ST_PUBLIC(name, ...) #name, +-#include "st_public_tmp.h" +- NULL +-}; +- +-static boolean +-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +-{ +- st_proc *procs = (st_proc *) stapi; +- void *handle; +- Dl_info info; +- const char **name; +- +- if (!dladdr(sym, &info)) +- return FALSE; +- handle = dlopen(info.dli_fname, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE); +- if (!handle) +- return FALSE; +- +- for (name = egl_g3d_st_names; *name; name++) { +- st_proc proc = (st_proc) dlsym(handle, *name); +- if (!proc) { +- _eglLog(_EGL_WARNING, "%s is missing in %s", *name, info.dli_fname); +- memset(stapi, 0, sizeof(*stapi)); +- dlclose(handle); +- return FALSE; +- } +- *procs++ = proc; +- } +- +- dlclose(handle); +- return TRUE; +-} +- +-#else /* HAVE_DLADDR */ +- +-static boolean +-egl_g3d_fill_st(struct egl_g3d_st *stapi, void *sym) +-{ +-#define ST_PUBLIC(name, ...) stapi->name = name; +-#include "st_public_tmp.h" +- return TRUE; +-} +- +-#endif /* HAVE_DLADDR */ +- +-static boolean +-egl_g3d_init_st(struct egl_g3d_st *stapi, const char *api) +-{ +- void *handle, *sym; +- boolean res = FALSE; +- +- /* already initialized */ +- if (stapi->st_notify_swapbuffers != NULL) +- return TRUE; +- +- handle = dlopen(NULL, RTLD_LAZY | RTLD_LOCAL); +- if (!handle) +- return FALSE; +- +- sym = dlsym(handle, api); +- if (sym && egl_g3d_fill_st(stapi, sym)) +- res = TRUE; +- +- dlclose(handle); +- return res; +-} +- +-static struct { +- const char *symbol; +- EGLint api_bit; +-} egl_g3d_st_info[NUM_EGL_G3D_STS] = { +- { "st_api_OpenGL_ES1", EGL_OPENGL_ES_BIT }, +- { "st_api_OpenVG", EGL_OPENVG_BIT }, +- { "st_api_OpenGL_ES2", EGL_OPENGL_ES2_BIT }, +- { "st_api_OpenGL", EGL_OPENGL_BIT }, +-}; +- +-const struct egl_g3d_st * +-egl_g3d_get_st(enum egl_g3d_st_api api) +-{ +- static struct egl_g3d_st all_trackers[NUM_EGL_G3D_STS]; +- +- if (egl_g3d_init_st(&all_trackers[api], egl_g3d_st_info[api].symbol)) { +- all_trackers[api].api_bit = egl_g3d_st_info[api].api_bit; +- return &all_trackers[api]; +- } +- else { +- return NULL; +- } +-} +diff --git a/src/gallium/state_trackers/egl/common/egl_st.h b/src/gallium/state_trackers/egl/common/egl_st.h +deleted file mode 100644 +index 8fb464b..0000000 +--- a/src/gallium/state_trackers/egl/common/egl_st.h ++++ /dev/null +@@ -1,73 +0,0 @@ +-/* +- * Mesa 3-D graphics library +- * Version: 7.8 +- * +- * Copyright (C) 2009-2010 Chia-I Wu <olv@0xlab.org> +- * +- * 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 +- * BRIAN PAUL 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 _EGL_ST_H_ +-#define _EGL_ST_H_ +- +-#include "GL/gl.h" /* for GL types */ +-#include "GL/internal/glcore.h" /* for __GLcontextModes */ +- +-#include "pipe/p_compiler.h" +-#include "pipe/p_format.h" +-#include "pipe/p_context.h" +- +-/* avoid calling st functions directly */ +-#if 1 +- +-#define ST_SURFACE_FRONT_LEFT 0 +-#define ST_SURFACE_BACK_LEFT 1 +-#define ST_SURFACE_FRONT_RIGHT 2 +-#define ST_SURFACE_BACK_RIGHT 3 +- +-#define ST_TEXTURE_2D 0x2 +- +-struct st_context; +-struct st_framebuffer; +-typedef void (*st_proc)(); +- +-#else +-#include "state_tracker/st_public.h" +-#endif +- +-/* remember to update egl_g3d_get_st() when update the enums */ +-enum egl_g3d_st_api { +- EGL_G3D_ST_OPENGL_ES = 0, +- EGL_G3D_ST_OPENVG, +- EGL_G3D_ST_OPENGL_ES2, +- EGL_G3D_ST_OPENGL, +- +- NUM_EGL_G3D_STS +-}; +- +-struct egl_g3d_st { +-#define ST_PUBLIC(name, ret, ...) ret (*name)(__VA_ARGS__); +-#include "st_public_tmp.h" +- /* fields must be added here */ +- EGLint api_bit; +-}; +- +-const struct egl_g3d_st * +-egl_g3d_get_st(enum egl_g3d_st_api api); +- +-#endif /* _EGL_ST_H_ */ +diff --git a/src/gallium/state_trackers/egl/common/st_public_tmp.h b/src/gallium/state_trackers/egl/common/st_public_tmp.h +deleted file mode 100644 +index 507a0ec..0000000 +--- a/src/gallium/state_trackers/egl/common/st_public_tmp.h ++++ /dev/null +@@ -1,20 +0,0 @@ +-ST_PUBLIC(st_create_context, struct st_context *, struct pipe_context *pipe, const __GLcontextModes *visual, struct st_context *share) +-ST_PUBLIC(st_destroy_context, void, struct st_context *st) +-ST_PUBLIC(st_copy_context_state, void, struct st_context *dst, struct st_context *src, uint mask) +-ST_PUBLIC(st_create_framebuffer, struct st_framebuffer *, const __GLcontextModes *visual, enum pipe_format colorFormat, enum pipe_format depthFormat, enum pipe_format stencilFormat, uint width, uint height, void *privateData) +-ST_PUBLIC(st_resize_framebuffer, void, struct st_framebuffer *stfb, uint width, uint height) +-ST_PUBLIC(st_set_framebuffer_surface, void, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface *surf) +-ST_PUBLIC(st_get_framebuffer_dimensions, void, struct st_framebuffer *stfb, uint *width, uint *height) +-ST_PUBLIC(st_get_framebuffer_surface, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_surface **surface) +-ST_PUBLIC(st_get_framebuffer_texture, int, struct st_framebuffer *stfb, uint surfIndex, struct pipe_texture **texture) +-ST_PUBLIC(st_framebuffer_private, void *, struct st_framebuffer *stfb) +-ST_PUBLIC(st_unreference_framebuffer, void, struct st_framebuffer *stfb) +-ST_PUBLIC(st_make_current, GLboolean, struct st_context *st, struct st_framebuffer *draw, struct st_framebuffer *read) +-ST_PUBLIC(st_get_current, struct st_context *, void) +-ST_PUBLIC(st_flush, void, struct st_context *st, uint pipeFlushFlags, struct pipe_fence_handle **fence) +-ST_PUBLIC(st_finish, void, struct st_context *st) +-ST_PUBLIC(st_notify_swapbuffers, void, struct st_framebuffer *stfb) +-ST_PUBLIC(st_bind_texture_surface, int, struct pipe_surface *ps, int target, int level, enum pipe_format format) +-ST_PUBLIC(st_unbind_texture_surface, int, struct pipe_surface *ps, int target, int level) +-ST_PUBLIC(st_get_proc_address, st_proc, const char *procname) +-#undef ST_PUBLIC +-- +1.6.5 + |