/*
- * Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
+ * Copyright 2012-2014, Haiku, Inc. All Rights Reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
#include "GLView.h"
-#include "main/context.h"
-#include "main/framebuffer.h"
-#include "main/renderbuffer.h"
#include "pipe/p_format.h"
#include "util/u_atomic.h"
+#include "util/u_format.h"
#include "util/u_memory.h"
+#include "util/u_inlines.h"
#include "hgl_context.h"
#define ERROR(x...) printf("hgl:state_tracker: " x)
+// Perform a safe void to hgl_context cast
+static INLINE struct hgl_context*
+hgl_st_context(struct st_context_iface *stctxi)
+{
+ struct hgl_context* context;
+ assert(stctxi);
+ context = (struct hgl_context*)stctxi->st_manager_private;
+ assert(context);
+ return context;
+}
+
+
+// Perform a safe void to hgl_buffer cast
+static INLINE struct hgl_buffer*
+hgl_st_framebuffer(struct st_framebuffer_iface *stfbi)
+{
+ struct hgl_buffer* buffer;
+ assert(stfbi);
+ buffer = (struct hgl_buffer*)stfbi->st_manager_private;
+ assert(buffer);
+ return buffer;
+}
+
+
static boolean
-hgl_st_framebuffer_flush_front(struct st_context_iface *stctx,
- struct st_framebuffer_iface* stfb, enum st_attachment_type statt)
+hgl_st_framebuffer_flush_front(struct st_context_iface *stctxi,
+ struct st_framebuffer_iface* stfbi, enum st_attachment_type statt)
{
CALLED();
- struct hgl_context* context = (struct hgl_context*)stfb->st_manager_private;
-
- if (!context) {
- ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__);
- return FALSE;
- }
+ //struct hgl_context* context = hgl_st_context(stctxi);
+ //struct hgl_buffer* buffer = hgl_st_context(stfbi);
#if 0
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
}
+static boolean
+hgl_st_framebuffer_validate_textures(struct st_framebuffer_iface *stfbi,
+ unsigned width, unsigned height, unsigned mask)
+{
+ struct hgl_buffer* buffer;
+ enum st_attachment_type i;
+ struct pipe_resource templat;
+
+ CALLED();
+
+ buffer = hgl_st_framebuffer(stfbi);
+
+ if (buffer->width != width || buffer->height != height) {
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++)
+ pipe_resource_reference(&buffer->textures[i], NULL);
+ }
+
+ memset(&templat, 0, sizeof(templat));
+ templat.target = buffer->target;
+ templat.width0 = width;
+ templat.height0 = height;
+ templat.depth0 = 1;
+ templat.array_size = 1;
+ templat.last_level = 0;
+
+ for (i = 0; i < ST_ATTACHMENT_COUNT; i++) {
+ enum pipe_format format;
+ unsigned bind;
+
+ switch (i) {
+ case ST_ATTACHMENT_FRONT_LEFT:
+ case ST_ATTACHMENT_BACK_LEFT:
+ case ST_ATTACHMENT_FRONT_RIGHT:
+ case ST_ATTACHMENT_BACK_RIGHT:
+ format = buffer->visual->color_format;
+ bind = PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_RENDER_TARGET;
+ break;
+ case ST_ATTACHMENT_DEPTH_STENCIL:
+ format = buffer->visual->depth_stencil_format;
+ bind = PIPE_BIND_DEPTH_STENCIL;
+ break;
+ default:
+ format = PIPE_FORMAT_NONE;
+ bind = 0;
+ break;
+ }
+
+ if (format != PIPE_FORMAT_NONE) {
+ templat.format = format;
+ templat.bind = bind;
+ buffer->textures[i] = buffer->screen->resource_create(buffer->screen,
+ &templat);
+ if (!buffer->textures[i])
+ return FALSE;
+ }
+ }
+
+ buffer->width = width;
+ buffer->height = height;
+ buffer->mask = mask;
+
+ return TRUE;
+}
+
+
/**
* Called by the st manager to validate the framebuffer (allocate
* its resources).
*/
static boolean
-hgl_st_framebuffer_validate(struct st_context_iface *stctx,
+hgl_st_framebuffer_validate(struct st_context_iface *stctxi,
struct st_framebuffer_iface *stfbi, const enum st_attachment_type *statts,
unsigned count, struct pipe_resource **out)
{
+ struct hgl_context* context;
+ struct hgl_buffer* buffer;
+ unsigned stAttachmentMask, newMask;
+ unsigned i;
+ boolean resized;
+
CALLED();
- if (!stfbi) {
- ERROR("%s: Invalid st framebuffer interface!\n", __func__);
- return FALSE;
- }
+ context = hgl_st_context(stctxi);
+ buffer = hgl_st_framebuffer(stfbi);
- struct hgl_context* context = (struct hgl_context*)stfbi->st_manager_private;
+ //int32 width = 0;
+ //int32 height = 0;
+ //get_bitmap_size(context->bitmap, &width, &height);
- if (!context) {
- ERROR("%s: Couldn't obtain valid hgl_context!\n", __func__);
- return FALSE;
- }
+ // Build mask of current attachments
+ stAttachmentMask = 0;
+ for (i = 0; i < count; i++)
+ stAttachmentMask |= 1 << statts[i];
- int32 width = 0;
- int32 height = 0;
- get_bitmap_size(context->bitmap, &width, &height);
+ newMask = stAttachmentMask & ~buffer->mask;
- struct pipe_resource templat;
- memset(&templat, 0, sizeof(templat));
- templat.target = PIPE_TEXTURE_RECT;
- templat.width0 = width;
- templat.height0 = height;
- templat.depth0 = 1;
- templat.array_size = 1;
- templat.usage = PIPE_USAGE_DEFAULT;
-
- if (context->stVisual && context->manager && context->manager->screen) {
- TRACE("%s: Updating resources\n", __func__);
- for (unsigned i = 0; i < count; i++) {
- enum pipe_format format = PIPE_FORMAT_NONE;
- unsigned bind = 0;
-
- switch(statts[i]) {
- case ST_ATTACHMENT_FRONT_LEFT:
- case ST_ATTACHMENT_BACK_LEFT:
- format = context->stVisual->color_format;
- bind = PIPE_BIND_DISPLAY_TARGET
- | PIPE_BIND_RENDER_TARGET;
- break;
- case ST_ATTACHMENT_DEPTH_STENCIL:
- format = context->stVisual->depth_stencil_format;
- bind = PIPE_BIND_DEPTH_STENCIL;
- break;
- case ST_ATTACHMENT_ACCUM:
- format = context->stVisual->accum_format;
- bind = PIPE_BIND_RENDER_TARGET;
- break;
- default:
- format = PIPE_FORMAT_NONE;
- break;
- }
-
- if (format != PIPE_FORMAT_NONE) {
- templat.format = format;
- templat.bind = bind;
-
- struct pipe_screen* screen = context->manager->screen;
- context->textures[i] = screen->resource_create(screen, &templat);
- out[i] = context->textures[i];
- }
- }
+ resized = (buffer->width != context->width)
+ || (buffer->height != context->height);
+
+ if (resized || newMask) {
+ boolean ret;
+ TRACE("%s: resize event. old: %d x %d; new: %d x %d\n", __func__,
+ buffer->width, buffer->height, context->width, context->height);
+
+ ret = hgl_st_framebuffer_validate_textures(stfbi,
+ context->width, context->height, stAttachmentMask);
+
+ if (!ret)
+ return ret;
+
+ // TODO: Simply update attachments
+ //if (!resized) {
+
+ //}
+ }
+
+ for (i = 0; i < count; i++) {
+ out[i] = NULL;
+ pipe_resource_reference(&out[i], buffer->textures[statts[i]]);
}
return TRUE;
switch (param) {
case ST_MANAGER_BROKEN_INVALIDATE:
- TRACE("%s: TODO: How should we handle BROKEN_INVALIDATE calls?\n",
- __func__);
- // For now we force validation of the framebuffer.
return 1;
}
struct hgl_buffer *
hgl_create_st_framebuffer(struct hgl_context* context)
{
+ struct hgl_buffer *buffer;
CALLED();
- struct hgl_buffer *buffer = CALLOC_STRUCT(hgl_buffer);
-
+ // Our requires before creating a framebuffer
assert(context);
+ assert(context->screen);
assert(context->stVisual);
- if (buffer) {
- // Copy context visual into framebuffer
- memcpy(&buffer->visual, context->stVisual, sizeof(struct st_visual));
+ buffer = CALLOC_STRUCT(hgl_buffer);
+ assert(buffer);
- // calloc and configure our st_framebuffer interface
- buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);
- if (!buffer->stfbi) {
- ERROR("%s: Couldn't calloc framebuffer!\n", __func__);
- return NULL;
- }
+ // calloc and configure our st_framebuffer interface
+ buffer->stfbi = CALLOC_STRUCT(st_framebuffer_iface);
+ assert(buffer->stfbi);
- struct st_framebuffer_iface* stfbi = buffer->stfbi;
- p_atomic_set(&stfbi->stamp, 1);
- stfbi->flush_front = hgl_st_framebuffer_flush_front;
- stfbi->validate = hgl_st_framebuffer_validate;
- stfbi->st_manager_private = (void*)context;
- stfbi->visual = &buffer->visual;
+ // Prepare our buffer
+ buffer->visual = context->stVisual;
+ buffer->screen = context->screen;
- // TODO: Do we need linked list?
- }
+ if (context->screen->get_param(buffer->screen, PIPE_CAP_NPOT_TEXTURES))
+ buffer->target = PIPE_TEXTURE_2D;
+ else
+ buffer->target = PIPE_TEXTURE_RECT;
+
+ // Prepare our state_tracker interface
+ buffer->stfbi->flush_front = hgl_st_framebuffer_flush_front;
+ buffer->stfbi->validate = hgl_st_framebuffer_validate;
+ buffer->stfbi->visual = context->stVisual;
+
+ p_atomic_set(&buffer->stfbi->stamp, 1);
+ buffer->stfbi->st_manager_private = (void*)buffer;
- return buffer;
+ return buffer;
}
struct st_manager *
-hgl_create_st_manager(struct pipe_screen* screen)
+hgl_create_st_manager(struct hgl_context* context)
{
+ struct st_manager* manager;
+
CALLED();
- assert(screen);
- struct st_manager* manager = CALLOC_STRUCT(st_manager);
+ // Required things
+ assert(context);
+ assert(context->screen);
- if (!manager) {
- ERROR("%s: Couldn't allocate state tracker manager!\n", __func__);
- return NULL;
- }
+ manager = CALLOC_STRUCT(st_manager);
+ assert(manager);
//manager->display = dpy;
- manager->screen = screen;
+ manager->screen = context->screen;
manager->get_param = hgl_st_manager_get_param;
return manager;
struct st_visual*
hgl_create_st_visual(ulong options)
{
- struct st_visual* visual = CALLOC_STRUCT(st_visual);
- if (!visual) {
- ERROR("%s: Couldn't allocate st_visual\n", __func__);
- return NULL;
- }
+ struct st_visual* visual;
- // Calculate visual configuration
- const GLboolean rgbFlag = ((options & BGL_INDEX) == 0);
- const GLboolean alphaFlag = ((options & BGL_ALPHA) == BGL_ALPHA);
- const GLboolean dblFlag = ((options & BGL_DOUBLE) == BGL_DOUBLE);
- const GLboolean stereoFlag = false;
- const GLboolean depthFlag = ((options & BGL_DEPTH) == BGL_DEPTH);
- const GLboolean stencilFlag = ((options & BGL_STENCIL) == BGL_STENCIL);
- const GLboolean accumFlag = ((options & BGL_ACCUM) == BGL_ACCUM);
-
- const GLint red = rgbFlag ? 8 : 5;
- const GLint green = rgbFlag ? 8 : 5;
- const GLint blue = rgbFlag ? 8 : 5;
- const GLint alpha = alphaFlag ? 8 : 0;
-
- TRACE("rgb :\t%d\n", (bool)rgbFlag);
- TRACE("alpha :\t%d\n", (bool)alphaFlag);
- TRACE("dbl :\t%d\n", (bool)dblFlag);
- TRACE("stereo :\t%d\n", (bool)stereoFlag);
- TRACE("depth :\t%d\n", (bool)depthFlag);
- TRACE("stencil :\t%d\n", (bool)stencilFlag);
- TRACE("accum :\t%d\n", (bool)accumFlag);
- TRACE("red :\t%d\n", red);
- TRACE("green :\t%d\n", green);
- TRACE("blue :\t%d\n", blue);
- TRACE("alpha :\t%d\n", alpha);
+ CALLED();
+
+ visual = CALLOC_STRUCT(st_visual);
+ assert(visual);
// Determine color format
- if (red == 8) {
- // Color format
- if (alpha == 8)
- visual->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
- else
- visual->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
-
- // Depth buffer
- if (depthFlag)
- visual->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
- else
- visual->depth_stencil_format = PIPE_FORMAT_NONE;
- } else {
+ if ((options & BGL_INDEX) != 0) {
+ // Index color
visual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
-
// TODO: Indexed color depth buffer?
visual->depth_stencil_format = PIPE_FORMAT_NONE;
+ } else {
+ // RGB color
+ visual->color_format = (options & BGL_ALPHA)
+ ? PIPE_FORMAT_BGRA8888_UNORM : PIPE_FORMAT_BGRX8888_UNORM;
+ // TODO: Determine additional stencil formats
+ visual->depth_stencil_format = (options & BGL_DEPTH)
+ ? PIPE_FORMAT_Z24_UNORM_S8_UINT : PIPE_FORMAT_NONE;
}
visual->accum_format = (options & BGL_ACCUM)
visual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
visual->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
- if (dblFlag) {
+ if ((options & BGL_DOUBLE) != 0) {
visual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
visual->render_buffer = ST_ATTACHMENT_BACK_LEFT;
}
- if (stereoFlag) {
+ #if 0
+ if ((options & BGL_STEREO) != 0) {
visual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
- if (dblFlag)
+ if ((options & BGL_DOUBLE) != 0)
visual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
}
+ #endif
if ((options & BGL_DEPTH) || (options & BGL_STENCIL))
visual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
+ TRACE("%s: Visual color format: %s\n", __func__,
+ util_format_name(visual->color_format));
+
return visual;
}
#include "bitmap_wrapper.h"
extern "C" {
#include "glapi/glapi.h"
-#include "main/viewport.h"
#include "pipe/p_format.h"
#include "state_tracker/st_cb_fbo.h"
#include "state_tracker/st_cb_flush.h"
#include "state_tracker/st_manager.h"
#include "state_tracker/sw_winsys.h"
#include "sw/hgl/hgl_sw_winsys.h"
+#include "util/u_atomic.h"
#include "util/u_memory.h"
#include "target-helpers/inline_sw_helper.h"
// Set up the initial things our context needs
context->bitmap = bitmap;
context->colorSpace = get_bitmap_color_space(bitmap);
+ context->screen = fScreen;
context->draw = NULL;
context->read = NULL;
context->st = NULL;
}
// Create state_tracker manager
- context->manager = hgl_create_st_manager(fScreen);
+ context->manager = hgl_create_st_manager(context);
// Create state tracker visual
context->stVisual = hgl_create_st_visual(fOptions);
api->make_current(context->api, context->st, context->draw->stfbi,
context->read->stfbi);
- if (context->textures[ST_ATTACHMENT_BACK_LEFT]
- && context->textures[ST_ATTACHMENT_DEPTH_STENCIL]
- && context->postProcess) {
- TRACE("Postprocessing textures...\n");
- pp_init_fbos(context->postProcess,
- context->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
- context->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
- }
+ //if (context->textures[ST_ATTACHMENT_BACK_LEFT]
+ // && context->textures[ST_ATTACHMENT_DEPTH_STENCIL]
+ // && context->postProcess) {
+ // TRACE("Postprocessing textures...\n");
+ // pp_init_fbos(context->postProcess,
+ // context->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
+ // context->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
+ //}
context->bitmap = bitmap;
//context->st->pipe->priv = context;
}
-void
-GalliumContext::ResizeViewport(int32 width, int32 height)
+bool
+GalliumContext::Validate(uint32 width, uint32 height)
{
CALLED();
- for (context_id i = 0; i < CONTEXT_MAX; i++) {
- if (fContext[i] && fContext[i]->st) {
- struct st_context *stContext = (struct st_context*)fContext[i]->st;
- // TODO: _mesa_set_viewport needs to be removed for something st_api?
- _mesa_set_viewport(stContext->ctx, 0, 0, 0, width, height);
- st_manager_validate_framebuffers(stContext);
- }
+
+ if (!fContext[fCurrentContext]) {
+ return false;
+ }
+
+ if (fContext[fCurrentContext]->width != width
+ || fContext[fCurrentContext]->height != height) {
+ Invalidate(width, height);
+ return false;
}
+ return true;
+}
+
+
+void
+GalliumContext::Invalidate(uint32 width, uint32 height)
+{
+ CALLED();
+
+ assert(fContext[fCurrentContext]);
+
+ // Update st_context dimensions
+ fContext[fCurrentContext]->width = width;
+ fContext[fCurrentContext]->height = height;
+
+ // Is this the best way to invalidate?
+ p_atomic_inc(&fContext[fCurrentContext]->read->stfbi->stamp);
+ p_atomic_inc(&fContext[fCurrentContext]->draw->stfbi->stamp);
}