mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 20:28:04 +02:00
haiku: Add first Haiku renderer (softpipe)
* This shared library gets parsed by the system as a system "add-on"
This commit is contained in:
parent
c9f1217e1f
commit
8730236d1a
9 changed files with 1249 additions and 5 deletions
528
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
Normal file
528
src/gallium/targets/haiku-softpipe/GalliumContext.cpp
Normal file
|
|
@ -0,0 +1,528 @@
|
|||
/*
|
||||
* Copyright 2012, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include "GalliumContext.h"
|
||||
|
||||
#include "GLView.h"
|
||||
|
||||
#include "bitmap_wrapper.h"
|
||||
#include "hgl_sw_winsys.h"
|
||||
extern "C" {
|
||||
#include "glapi/glapi.h"
|
||||
#include "main/context.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "main/renderbuffer.h"
|
||||
#include "pipe/p_format.h"
|
||||
#include "state_tracker/st_cb_fbo.h"
|
||||
#include "state_tracker/st_cb_flush.h"
|
||||
#include "state_tracker/st_context.h"
|
||||
#include "state_tracker/st_gl_api.h"
|
||||
#include "state_tracker/st_manager.h"
|
||||
#include "state_tracker/sw_winsys.h"
|
||||
#ifdef HAVE_LLVM
|
||||
#include "llvmpipe/lp_public.h"
|
||||
#else
|
||||
#include "softpipe/sp_public.h"
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define TRACE_CONTEXT
|
||||
#ifdef TRACE_CONTEXT
|
||||
# define TRACE(x...) printf("GalliumContext: " x)
|
||||
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
# define CALLED()
|
||||
#endif
|
||||
#define ERROR(x...) printf("GalliumContext: " x)
|
||||
|
||||
|
||||
static void
|
||||
hgl_viewport(struct gl_context* glContext, GLint x, GLint y,
|
||||
GLsizei width, GLsizei height)
|
||||
{
|
||||
TRACE("%s(glContext: %p, x: %d, y: %d, w: %d, h: %d\n", __func__,
|
||||
glContext, x, y, width, height);
|
||||
|
||||
struct gl_framebuffer *draw = glContext->WinSysDrawBuffer;
|
||||
struct gl_framebuffer *read = glContext->WinSysReadBuffer;
|
||||
|
||||
// TODO: SLOW! We need to check for changes in bitmap vs gl_framebuffer
|
||||
// size before doing a _mesa_resize_framebuffer.
|
||||
if (draw)
|
||||
_mesa_resize_framebuffer(glContext, draw, width, height);
|
||||
if (read)
|
||||
_mesa_resize_framebuffer(glContext, read, width, height);
|
||||
}
|
||||
|
||||
|
||||
static st_visual*
|
||||
hgl_fill_st_visual(gl_config* glVisual)
|
||||
{
|
||||
struct st_visual* stVisual = CALLOC_STRUCT(st_visual);
|
||||
if (!stVisual) {
|
||||
ERROR("%s: Couldn't allocate st_visual\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Determine color format
|
||||
if (glVisual->redBits == 8) {
|
||||
if (glVisual->alphaBits == 8)
|
||||
stVisual->color_format = PIPE_FORMAT_B8G8R8A8_UNORM;
|
||||
else
|
||||
stVisual->color_format = PIPE_FORMAT_B8G8R8X8_UNORM;
|
||||
} else {
|
||||
stVisual->color_format = PIPE_FORMAT_B5G6R5_UNORM;
|
||||
}
|
||||
|
||||
// Determine depth stencil format
|
||||
switch (glVisual->depthBits) {
|
||||
default:
|
||||
case 0:
|
||||
stVisual->depth_stencil_format = PIPE_FORMAT_NONE;
|
||||
break;
|
||||
case 16:
|
||||
stVisual->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
|
||||
break;
|
||||
case 24:
|
||||
if (glVisual->stencilBits == 0) {
|
||||
stVisual->depth_stencil_format = PIPE_FORMAT_Z24X8_UNORM;
|
||||
// or PIPE_FORMAT_X8Z24_UNORM?
|
||||
} else {
|
||||
stVisual->depth_stencil_format = PIPE_FORMAT_Z24_UNORM_S8_UINT;
|
||||
// or PIPE_FORMAT_S8_UINT_Z24_UNORM?
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
stVisual->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
|
||||
break;
|
||||
}
|
||||
|
||||
stVisual->accum_format = (glVisual->haveAccumBuffer)
|
||||
? PIPE_FORMAT_R16G16B16A16_SNORM : PIPE_FORMAT_NONE;
|
||||
|
||||
stVisual->buffer_mask |= ST_ATTACHMENT_FRONT_LEFT_MASK;
|
||||
stVisual->render_buffer = ST_ATTACHMENT_FRONT_LEFT;
|
||||
if (glVisual->doubleBufferMode) {
|
||||
stVisual->buffer_mask |= ST_ATTACHMENT_BACK_LEFT_MASK;
|
||||
stVisual->render_buffer = ST_ATTACHMENT_BACK_LEFT;
|
||||
}
|
||||
|
||||
if (glVisual->stereoMode) {
|
||||
stVisual->buffer_mask |= ST_ATTACHMENT_FRONT_RIGHT_MASK;
|
||||
if (glVisual->doubleBufferMode)
|
||||
stVisual->buffer_mask |= ST_ATTACHMENT_BACK_RIGHT_MASK;
|
||||
}
|
||||
|
||||
if (glVisual->haveDepthBuffer || glVisual->haveStencilBuffer)
|
||||
stVisual->buffer_mask |= ST_ATTACHMENT_DEPTH_STENCIL_MASK;
|
||||
|
||||
return stVisual;
|
||||
}
|
||||
|
||||
|
||||
static INLINE unsigned
|
||||
round_up(unsigned n, unsigned multiple)
|
||||
{
|
||||
return (n + multiple - 1) & ~(multiple - 1);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
hook_stm_get_param(struct st_manager *smapi, enum st_manager_param param)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
GalliumContext::GalliumContext(ulong options)
|
||||
:
|
||||
fOptions(options),
|
||||
fCurrentContext(0),
|
||||
fScreen(NULL)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// Make all contexts a known value
|
||||
for (context_id i = 0; i < CONTEXT_MAX; i++)
|
||||
fContext[i] = NULL;
|
||||
|
||||
CreateScreen();
|
||||
|
||||
pipe_mutex_init(fMutex);
|
||||
}
|
||||
|
||||
|
||||
GalliumContext::~GalliumContext()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// Destroy our contexts
|
||||
pipe_mutex_lock(fMutex);
|
||||
for (context_id i = 0; i < CONTEXT_MAX; i++)
|
||||
DestroyContext(i);
|
||||
pipe_mutex_unlock(fMutex);
|
||||
|
||||
pipe_mutex_destroy(fMutex);
|
||||
|
||||
// TODO: Destroy fScreen
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumContext::CreateScreen()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// Allocate winsys and attach callback hooks
|
||||
struct sw_winsys* winsys = hgl_create_sw_winsys();
|
||||
|
||||
if (!winsys) {
|
||||
ERROR("%s: Couldn't allocate sw_winsys!\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LLVM
|
||||
fScreen = llvmpipe_create_screen(winsys);
|
||||
#else
|
||||
fScreen = softpipe_create_screen(winsys);
|
||||
#endif
|
||||
|
||||
if (fScreen == NULL) {
|
||||
ERROR("%s: Couldn't create screen!\n", __FUNCTION__);
|
||||
FREE(winsys);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
const char* driverName = fScreen->get_name(fScreen);
|
||||
ERROR("%s: Using %s driver.\n", __func__, driverName);
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
context_id
|
||||
GalliumContext::CreateContext(Bitmap *bitmap)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
struct hgl_context* context = CALLOC_STRUCT(hgl_context);
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: Couldn't create pipe context!\n", __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set up the initial things our context needs
|
||||
context->bitmap = bitmap;
|
||||
context->colorSpace = get_bitmap_color_space(bitmap);
|
||||
context->draw = NULL;
|
||||
context->read = NULL;
|
||||
context->st = NULL;
|
||||
|
||||
context->api = st_gl_api_create();
|
||||
if (!context->api) {
|
||||
ERROR("%s: Couldn't obtain Mesa state tracker API!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
context->manager = CALLOC_STRUCT(st_manager);
|
||||
if (!context->manager) {
|
||||
ERROR("%s: Couldn't allocate Mesa state tracker manager!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
context->manager->get_param = hook_stm_get_param;
|
||||
|
||||
// Calculate visual configuration
|
||||
const GLboolean rgbFlag = ((fOptions & BGL_INDEX) == 0);
|
||||
const GLboolean alphaFlag = ((fOptions & BGL_ALPHA) == BGL_ALPHA);
|
||||
const GLboolean dblFlag = ((fOptions & BGL_DOUBLE) == BGL_DOUBLE);
|
||||
const GLboolean stereoFlag = false;
|
||||
const GLint depth = (fOptions & BGL_DEPTH) ? 24 : 0;
|
||||
const GLint stencil = (fOptions & BGL_STENCIL) ? 8 : 0;
|
||||
const GLint accum = 0; // (options & BGL_ACCUM) ? 16 : 0;
|
||||
const GLint red = rgbFlag ? 8 : 0;
|
||||
const GLint green = rgbFlag ? 8 : 0;
|
||||
const GLint blue = rgbFlag ? 8 : 0;
|
||||
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", depth);
|
||||
TRACE("stencil :\t%d\n", stencil);
|
||||
TRACE("accum :\t%d\n", accum);
|
||||
TRACE("red :\t%d\n", red);
|
||||
TRACE("green :\t%d\n", green);
|
||||
TRACE("blue :\t%d\n", blue);
|
||||
TRACE("alpha :\t%d\n", alpha);
|
||||
|
||||
gl_config* glVisual = _mesa_create_visual(dblFlag, stereoFlag, red, green,
|
||||
blue, alpha, depth, stencil, accum, accum, accum, alpha ? accum : 0, 1);
|
||||
|
||||
if (!glVisual) {
|
||||
ERROR("%s: Couldn't create Mesa visual!\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACE("depthBits :\t%d\n", glVisual->depthBits);
|
||||
TRACE("stencilBits :\t%d\n", glVisual->stencilBits);
|
||||
|
||||
// Convert Mesa calculated visual into state tracker visual
|
||||
context->stVisual = hgl_fill_st_visual(glVisual);
|
||||
|
||||
context->draw = new GalliumFramebuffer(context->stVisual, (void*)this);
|
||||
context->read = new GalliumFramebuffer(context->stVisual, (void*)this);
|
||||
|
||||
if (!context->draw || !context->read) {
|
||||
ERROR("%s: Problem allocating framebuffer!\n", __func__);
|
||||
_mesa_destroy_visual(glVisual);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// We need to assign the screen *before* calling st_api create_context
|
||||
context->manager->screen = fScreen;
|
||||
|
||||
// Build state tracker attributes
|
||||
struct st_context_attribs attribs;
|
||||
memset(&attribs, 0, sizeof(attribs));
|
||||
attribs.options.force_glsl_extensions_warn = false;
|
||||
attribs.profile = ST_PROFILE_DEFAULT;
|
||||
attribs.visual = *context->stVisual;
|
||||
attribs.major = 1;
|
||||
attribs.minor = 0;
|
||||
//attribs.flags |= ST_CONTEXT_FLAG_DEBUG;
|
||||
|
||||
struct st_api* api = context->api;
|
||||
|
||||
// Create context using state tracker api call
|
||||
enum st_context_error result;
|
||||
context->st = api->create_context(api, context->manager, &attribs,
|
||||
&result, context->st);
|
||||
|
||||
if (!context->st) {
|
||||
ERROR("%s: Couldn't create mesa state tracker context!\n",
|
||||
__func__);
|
||||
switch (result) {
|
||||
case ST_CONTEXT_SUCCESS:
|
||||
ERROR("%s: State tracker error: SUCCESS?\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_NO_MEMORY:
|
||||
ERROR("%s: State tracker error: NO_MEMORY\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_BAD_API:
|
||||
ERROR("%s: State tracker error: BAD_API\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_BAD_VERSION:
|
||||
ERROR("%s: State tracker error: BAD_VERSION\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_BAD_FLAG:
|
||||
ERROR("%s: State tracker error: BAD_FLAG\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE:
|
||||
ERROR("%s: State tracker error: BAD_ATTRIBUTE\n", __func__);
|
||||
break;
|
||||
case ST_CONTEXT_ERROR_UNKNOWN_FLAG:
|
||||
ERROR("%s: State tracker error: UNKNOWN_FLAG\n", __func__);
|
||||
break;
|
||||
}
|
||||
|
||||
FREE(context);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Init Gallium3D Post Processing
|
||||
//context->postProcess = pp_init(fScreen, context->postProcessEnable);
|
||||
|
||||
assert(!context->st->st_manager_private);
|
||||
context->st->st_manager_private = (void*)this;
|
||||
|
||||
struct st_context *stContext = (struct st_context*)context->st;
|
||||
|
||||
stContext->ctx->Driver.Viewport = hgl_viewport;
|
||||
|
||||
// TODO: Closely review this next context logic...
|
||||
context_id contextNext = -1;
|
||||
|
||||
pipe_mutex_lock(fMutex);
|
||||
for (context_id i = 0; i < CONTEXT_MAX; i++) {
|
||||
if (fContext[i] == NULL) {
|
||||
fContext[i] = context;
|
||||
contextNext = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pipe_mutex_unlock(fMutex);
|
||||
|
||||
if (contextNext < 0) {
|
||||
ERROR("%s: The next context is invalid... something went wrong!\n",
|
||||
__func__);
|
||||
//st_destroy_context(context->st);
|
||||
FREE(context);
|
||||
_mesa_destroy_visual(glVisual);
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACE("%s: context #%" B_PRIu64 " is the next available context\n",
|
||||
__func__, contextNext);
|
||||
|
||||
return contextNext;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GalliumContext::DestroyContext(context_id contextID)
|
||||
{
|
||||
// fMutex should be locked *before* calling DestoryContext
|
||||
|
||||
// See if context is used
|
||||
if (!fContext[contextID])
|
||||
return;
|
||||
|
||||
if (fContext[contextID]->st) {
|
||||
fContext[contextID]->st->flush(fContext[contextID]->st, 0, NULL);
|
||||
fContext[contextID]->st->destroy(fContext[contextID]->st);
|
||||
}
|
||||
|
||||
if (fContext[contextID]->postProcess)
|
||||
pp_free(fContext[contextID]->postProcess);
|
||||
|
||||
// Delete framebuffer objects
|
||||
if (fContext[contextID]->read)
|
||||
delete fContext[contextID]->read;
|
||||
if (fContext[contextID]->draw)
|
||||
delete fContext[contextID]->draw;
|
||||
|
||||
if (fContext[contextID]->stVisual)
|
||||
FREE(fContext[contextID]->stVisual);
|
||||
|
||||
if (fContext[contextID]->manager)
|
||||
FREE(fContext[contextID]->manager);
|
||||
|
||||
FREE(fContext[contextID]);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumContext::SetCurrentContext(Bitmap *bitmap, context_id contextID)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (contextID < 0 || contextID > CONTEXT_MAX) {
|
||||
ERROR("%s: Invalid context ID range!\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
pipe_mutex_lock(fMutex);
|
||||
context_id oldContextID = fCurrentContext;
|
||||
struct hgl_context* context = fContext[contextID];
|
||||
pipe_mutex_unlock(fMutex);
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: Invalid context provided (#%" B_PRIu64 ")!\n",
|
||||
__func__, contextID);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
struct st_api* api = context->api;
|
||||
|
||||
if (!bitmap) {
|
||||
api->make_current(context->api, NULL, NULL, NULL);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// Everything seems valid, lets set the new context.
|
||||
fCurrentContext = contextID;
|
||||
|
||||
if (oldContextID > 0 && oldContextID != contextID) {
|
||||
fContext[oldContextID]->st->flush(fContext[oldContextID]->st,
|
||||
ST_FLUSH_FRONT, NULL);
|
||||
}
|
||||
|
||||
// We need to lock and unlock framebuffers before accessing them
|
||||
context->draw->Lock();
|
||||
context->read->Lock();
|
||||
api->make_current(context->api, context->st, context->draw->fBuffer,
|
||||
context->read->fBuffer);
|
||||
context->draw->Unlock();
|
||||
context->read->Unlock();
|
||||
|
||||
// TODO: Init textures before post-processing them
|
||||
#if 0
|
||||
pp_init_fbos(context->postProcess,
|
||||
context->textures[ST_ATTACHMENT_BACK_LEFT]->width0,
|
||||
context->textures[ST_ATTACHMENT_BACK_LEFT]->height0);
|
||||
#endif
|
||||
|
||||
context->bitmap = bitmap;
|
||||
//context->st->pipe->priv = context;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumContext::SwapBuffers(context_id contextID)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
pipe_mutex_lock(fMutex);
|
||||
struct hgl_context *context = fContext[contextID];
|
||||
pipe_mutex_unlock(fMutex);
|
||||
|
||||
if (!context) {
|
||||
ERROR("%s: context not found\n", __func__);
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// TODO: Where did st_notify_swapbuffers go?
|
||||
//st_notify_swapbuffers(context->draw->stfb);
|
||||
|
||||
context->st->flush(context->st, ST_FLUSH_FRONT, NULL);
|
||||
|
||||
struct st_context *stContext = (struct st_context*)context->st;
|
||||
|
||||
unsigned nColorBuffers = stContext->state.framebuffer.nr_cbufs;
|
||||
for (unsigned i = 0; i < nColorBuffers; i++) {
|
||||
pipe_surface* surface = stContext->state.framebuffer.cbufs[i];
|
||||
if (!surface) {
|
||||
ERROR("%s: Color buffer %d invalid!\n", __func__, i);
|
||||
continue;
|
||||
}
|
||||
|
||||
TRACE("%s: Flushing color buffer #%d\n", __func__, i);
|
||||
|
||||
// We pass our destination bitmap to flush_fronbuffer which passes it
|
||||
// to the private winsys display call.
|
||||
fScreen->flush_frontbuffer(fScreen, surface->texture, 0, 0,
|
||||
context->bitmap);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO... should we flush the z stencil buffer?
|
||||
pipe_surface* zSurface = stContext->state.framebuffer.zsbuf;
|
||||
fScreen->flush_frontbuffer(fScreen, surface->texture, 0, 0,
|
||||
context->bitmap);
|
||||
#endif
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
83
src/gallium/targets/haiku-softpipe/GalliumContext.h
Normal file
83
src/gallium/targets/haiku-softpipe/GalliumContext.h
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright 2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
#ifndef GALLIUMCONTEXT_H
|
||||
#define GALLIUMCONTEXT_H
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <kernel/image.h>
|
||||
|
||||
extern "C" {
|
||||
#include "state_tracker/st_api.h"
|
||||
#include "pipe/p_compiler.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "postprocess/filters.h"
|
||||
#include "os/os_thread.h"
|
||||
}
|
||||
#include "bitmap_wrapper.h"
|
||||
#include "GalliumFramebuffer.h"
|
||||
|
||||
|
||||
#define CONTEXT_MAX 32
|
||||
|
||||
|
||||
typedef int64 context_id;
|
||||
|
||||
struct hgl_context
|
||||
{
|
||||
struct st_api* api;
|
||||
// State Tracker API
|
||||
struct st_manager* manager;
|
||||
// State Tracker Manager
|
||||
struct st_context_iface* st;
|
||||
// State Tracker Interface Object
|
||||
struct st_visual* stVisual;
|
||||
// State Tracker Visual
|
||||
|
||||
struct pipe_resource* textures[ST_ATTACHMENT_COUNT];
|
||||
|
||||
// Post processing
|
||||
struct pp_queue_t* postProcess;
|
||||
unsigned int postProcessEnable[PP_FILTERS];
|
||||
|
||||
Bitmap* bitmap;
|
||||
color_space colorSpace;
|
||||
|
||||
GalliumFramebuffer* draw;
|
||||
GalliumFramebuffer* read;
|
||||
};
|
||||
|
||||
|
||||
class GalliumContext {
|
||||
public:
|
||||
GalliumContext(ulong options);
|
||||
~GalliumContext();
|
||||
|
||||
context_id CreateContext(Bitmap* bitmap);
|
||||
void DestroyContext(context_id contextID);
|
||||
context_id GetCurrentContext() { return fCurrentContext; };
|
||||
status_t SetCurrentContext(Bitmap *bitmap,
|
||||
context_id contextID);
|
||||
|
||||
status_t SwapBuffers(context_id contextID);
|
||||
|
||||
private:
|
||||
status_t CreateScreen();
|
||||
void Flush();
|
||||
|
||||
ulong fOptions;
|
||||
|
||||
struct hgl_context* fContext[CONTEXT_MAX];
|
||||
context_id fCurrentContext;
|
||||
|
||||
struct pipe_screen* fScreen;
|
||||
pipe_mutex fMutex;
|
||||
};
|
||||
|
||||
|
||||
#endif /* GALLIUMCONTEXT_H */
|
||||
116
src/gallium/targets/haiku-softpipe/GalliumFramebuffer.cpp
Normal file
116
src/gallium/targets/haiku-softpipe/GalliumFramebuffer.cpp
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright 2012-2013, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include "GalliumFramebuffer.h"
|
||||
|
||||
extern "C" {
|
||||
#include "main/context.h"
|
||||
#include "main/framebuffer.h"
|
||||
#include "main/renderbuffer.h"
|
||||
#include "pipe/p_format.h"
|
||||
}
|
||||
|
||||
|
||||
#define TRACE_FRAMEBUFFER
|
||||
#ifdef TRACE_FRAEMBUFFER
|
||||
# define TRACE(x...) printf("GalliumFramebuffer: " x)
|
||||
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
# define CALLED()
|
||||
#endif
|
||||
#define ERROR(x...) printf("GalliumFramebuffer: " x)
|
||||
|
||||
|
||||
static boolean
|
||||
hgl_framebuffer_flush_front(struct st_context_iface *stctx,
|
||||
struct st_framebuffer_iface* stfb, enum st_attachment_type statt)
|
||||
{
|
||||
CALLED();
|
||||
// TODO: I have *NO* idea how we are going to access this data...
|
||||
|
||||
#if 0
|
||||
struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
|
||||
pipe_mutex_lock(stwfb->fb->mutex);
|
||||
|
||||
struct pipe_resource* resource = textures[statt];
|
||||
if (resource)
|
||||
stw_framebuffer_present_locked(...);
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static boolean
|
||||
hgl_framebuffer_validate(struct st_context_iface* stctx,
|
||||
struct st_framebuffer_iface* stfb,
|
||||
const enum st_attachment_type* statts, unsigned count,
|
||||
struct pipe_resource** out)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
GalliumFramebuffer::GalliumFramebuffer(struct st_visual* visual,
|
||||
void* privateContext)
|
||||
:
|
||||
fBuffer(NULL)
|
||||
{
|
||||
CALLED();
|
||||
fBuffer = CALLOC_STRUCT(st_framebuffer_iface);
|
||||
if (!fBuffer) {
|
||||
ERROR("%s: Couldn't calloc framebuffer!\n", __func__);
|
||||
return;
|
||||
}
|
||||
fBuffer->visual = visual;
|
||||
fBuffer->flush_front = hgl_framebuffer_flush_front;
|
||||
fBuffer->validate = hgl_framebuffer_validate;
|
||||
fBuffer->st_manager_private = privateContext;
|
||||
|
||||
pipe_mutex_init(fMutex);
|
||||
}
|
||||
|
||||
|
||||
GalliumFramebuffer::~GalliumFramebuffer()
|
||||
{
|
||||
CALLED();
|
||||
// We lock and unlock to try and make sure we wait for anything
|
||||
// using the framebuffer to finish
|
||||
Lock();
|
||||
if (!fBuffer) {
|
||||
ERROR("%s: Strange, no Gallium Framebuffer to free?\n", __func__);
|
||||
return;
|
||||
}
|
||||
FREE(fBuffer);
|
||||
Unlock();
|
||||
|
||||
pipe_mutex_destroy(fMutex);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumFramebuffer::Lock()
|
||||
{
|
||||
CALLED();
|
||||
pipe_mutex_lock(fMutex);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
GalliumFramebuffer::Unlock()
|
||||
{
|
||||
CALLED();
|
||||
pipe_mutex_unlock(fMutex);
|
||||
return B_OK;
|
||||
}
|
||||
34
src/gallium/targets/haiku-softpipe/GalliumFramebuffer.h
Normal file
34
src/gallium/targets/haiku-softpipe/GalliumFramebuffer.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright 2012, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
#ifndef GALLIUMFRAMEBUFFER_H
|
||||
#define GALLIUMFRAMEBUFFER_H
|
||||
|
||||
|
||||
extern "C" {
|
||||
#include "os/os_thread.h"
|
||||
#include "pipe/p_screen.h"
|
||||
#include "state_tracker/st_api.h"
|
||||
}
|
||||
|
||||
|
||||
class GalliumFramebuffer {
|
||||
public:
|
||||
GalliumFramebuffer(struct st_visual* visual,
|
||||
void* privateContext);
|
||||
~GalliumFramebuffer();
|
||||
status_t Lock();
|
||||
status_t Unlock();
|
||||
|
||||
struct st_framebuffer_iface* fBuffer;
|
||||
|
||||
private:
|
||||
pipe_mutex fMutex;
|
||||
};
|
||||
|
||||
|
||||
#endif /* GALLIUMFRAMEBUFFER_H */
|
||||
|
|
@ -1,21 +1,44 @@
|
|||
Import('*')
|
||||
|
||||
env.Prepend(LIBS = [
|
||||
ws_haiku,
|
||||
trace,
|
||||
rbug,
|
||||
mesa,
|
||||
glsl,
|
||||
gallium
|
||||
])
|
||||
|
||||
if True:
|
||||
env.Append(CPPDEFINES = [
|
||||
'GALLIUM_SOFTPIPE',
|
||||
'GALLIUM_RBUG',
|
||||
'GALLIUM_TRACE',
|
||||
])
|
||||
env.Prepend(LIBS = [softpipe])
|
||||
|
||||
env.Append(CPPPATH = [
|
||||
'#/src/mapi',
|
||||
'#/src/mesa',
|
||||
'#/src/mesa/main',
|
||||
'#/src/gallium/winsys/sw/hgl',
|
||||
'/boot/system/develop/headers/private',
|
||||
])
|
||||
|
||||
if env['llvm']:
|
||||
env.Append(CPPDEFINES = 'HAVE_LLVMPIPE')
|
||||
|
||||
softpipe_sources = [
|
||||
'haiku-softpipe.c'
|
||||
'haiku-softpipe.c',
|
||||
'GalliumContext.cpp',
|
||||
'GalliumFramebuffer.cpp',
|
||||
'SoftwareRenderer.cpp'
|
||||
]
|
||||
|
||||
module = env.StaticLibrary(
|
||||
target ='swpipe_haiku.a',
|
||||
# libswpipe gets turned into "Software Renderer" by the haiku package system
|
||||
module = env.SharedLibrary(
|
||||
target ='swpipe',
|
||||
source = softpipe_sources,
|
||||
SHLIBPREFIX = '',
|
||||
)
|
||||
|
||||
env.Alias('softpipe-haiku', module)
|
||||
|
|
|
|||
363
src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp
Normal file
363
src/gallium/targets/haiku-softpipe/SoftwareRenderer.cpp
Normal file
|
|
@ -0,0 +1,363 @@
|
|||
/*
|
||||
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* Philippe Houdoin, philippe.houdoin@free.fr
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
|
||||
|
||||
#include "SoftwareRenderer.h"
|
||||
|
||||
#include <Autolock.h>
|
||||
#include <interface/DirectWindowPrivate.h>
|
||||
#include <GraphicsDefs.h>
|
||||
#include <Screen.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <new>
|
||||
|
||||
|
||||
#define TRACE_SOFTWARE
|
||||
#ifdef TRACE_SOFTWARE
|
||||
# define TRACE(x...) printf("SoftwareRenderer: " x)
|
||||
# define CALLED() TRACE("CALLED: %s\n", __PRETTY_FUNCTION__)
|
||||
#else
|
||||
# define TRACE(x...)
|
||||
# define CALLED()
|
||||
#endif
|
||||
#define ERROR(x...) printf("SoftwareRenderer: " x)
|
||||
|
||||
|
||||
extern const char* color_space_name(color_space space);
|
||||
|
||||
|
||||
extern "C" _EXPORT BGLRenderer*
|
||||
instantiate_gl_renderer(BGLView *view, ulong opts, BGLDispatcher *dispatcher)
|
||||
{
|
||||
return new SoftwareRenderer(view, opts, dispatcher);
|
||||
}
|
||||
|
||||
SoftwareRenderer::SoftwareRenderer(BGLView *view, ulong options,
|
||||
BGLDispatcher* dispatcher)
|
||||
:
|
||||
BGLRenderer(view, options, dispatcher),
|
||||
fBitmap(NULL),
|
||||
fDirectModeEnabled(false),
|
||||
fInfo(NULL),
|
||||
fInfoLocker("info locker"),
|
||||
fOptions(options),
|
||||
fColorSpace(B_NO_COLOR_SPACE)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// Disable double buffer for the moment.
|
||||
options &= ~BGL_DOUBLE;
|
||||
|
||||
// Initialize the "Haiku Software GL Pipe"
|
||||
time_t beg;
|
||||
time_t end;
|
||||
beg = time(NULL);
|
||||
fContextObj = new GalliumContext(options);
|
||||
end = time(NULL);
|
||||
TRACE("Haiku Software GL Pipe initialization time: %f.\n",
|
||||
difftime(end, beg));
|
||||
|
||||
// Allocate a bitmap
|
||||
BRect b = view->Bounds();
|
||||
fColorSpace = BScreen(view->Window()).ColorSpace();
|
||||
TRACE("%s: Colorspace:\t%s\n", __func__, color_space_name(fColorSpace));
|
||||
|
||||
fWidth = (GLint)b.IntegerWidth();
|
||||
fHeight = (GLint)b.IntegerHeight();
|
||||
fNewWidth = fWidth;
|
||||
fNewHeight = fHeight;
|
||||
|
||||
_AllocateBitmap();
|
||||
|
||||
// Initialize the first "Haiku Software GL Pipe" context
|
||||
beg = time(NULL);
|
||||
fContextID = fContextObj->CreateContext(fBitmap);
|
||||
end = time(NULL);
|
||||
|
||||
if (fContextID < 0)
|
||||
ERROR("%s: There was an error creating the context!\n", __func__);
|
||||
else {
|
||||
TRACE("%s: Haiku Software GL Pipe context creation time: %f.\n",
|
||||
__func__, difftime(end, beg));
|
||||
}
|
||||
|
||||
if (!fContextObj->GetCurrentContext())
|
||||
LockGL();
|
||||
}
|
||||
|
||||
|
||||
SoftwareRenderer::~SoftwareRenderer()
|
||||
{
|
||||
CALLED();
|
||||
|
||||
if (fContextObj)
|
||||
delete fContextObj;
|
||||
if (fBitmap)
|
||||
delete fBitmap;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::LockGL()
|
||||
{
|
||||
// CALLED();
|
||||
BGLRenderer::LockGL();
|
||||
|
||||
color_space cs = BScreen(GLView()->Window()).ColorSpace();
|
||||
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (fDirectModeEnabled && fInfo != NULL) {
|
||||
fNewWidth = fInfo->window_bounds.right - fInfo->window_bounds.left;
|
||||
// + 1;
|
||||
fNewHeight = fInfo->window_bounds.bottom - fInfo->window_bounds.top;
|
||||
// + 1;
|
||||
}
|
||||
|
||||
if (fBitmap && cs == fColorSpace && fNewWidth == fWidth
|
||||
&& fNewHeight == fHeight) {
|
||||
fContextObj->SetCurrentContext(fBitmap, fContextID);
|
||||
return;
|
||||
}
|
||||
|
||||
fColorSpace = cs;
|
||||
fWidth = fNewWidth;
|
||||
fHeight = fNewHeight;
|
||||
|
||||
_AllocateBitmap();
|
||||
fContextObj->SetCurrentContext(fBitmap, fContextID);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::UnlockGL()
|
||||
{
|
||||
// CALLED();
|
||||
if ((fOptions & BGL_DOUBLE) == 0) {
|
||||
SwapBuffers();
|
||||
}
|
||||
fContextObj->SetCurrentContext(NULL, fContextID);
|
||||
BGLRenderer::UnlockGL();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::SwapBuffers(bool vsync)
|
||||
{
|
||||
// CALLED();
|
||||
if (!fBitmap)
|
||||
return;
|
||||
|
||||
BScreen screen(GLView()->Window());
|
||||
|
||||
fContextObj->SwapBuffers(fContextID);
|
||||
|
||||
BAutolock lock(fInfoLocker);
|
||||
|
||||
if (!fDirectModeEnabled || fInfo == NULL) {
|
||||
if (GLView()->LockLooperWithTimeout(1000) == B_OK) {
|
||||
GLView()->DrawBitmap(fBitmap, B_ORIGIN);
|
||||
GLView()->UnlockLooper();
|
||||
if (vsync)
|
||||
screen.WaitForRetrace();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// check the bitmap size still matches the size
|
||||
if (fInfo->window_bounds.bottom - fInfo->window_bounds.top
|
||||
!= fBitmap->Bounds().IntegerHeight()
|
||||
|| fInfo->window_bounds.right - fInfo->window_bounds.left
|
||||
!= fBitmap->Bounds().IntegerWidth()) {
|
||||
ERROR("%s: Bitmap size doesn't match size!\n", __func__);
|
||||
return;
|
||||
}
|
||||
uint8 bytesPerPixel = fInfo->bits_per_pixel / 8;
|
||||
uint32 bytesPerRow = fBitmap->BytesPerRow();
|
||||
for (uint32 i = 0; i < fInfo->clip_list_count; i++) {
|
||||
clipping_rect *clip = &fInfo->clip_list[i];
|
||||
int32 height = clip->bottom - clip->top + 1;
|
||||
int32 bytesWidth
|
||||
= (clip->right - clip->left + 1) * bytesPerPixel;
|
||||
bytesWidth -= bytesPerPixel;
|
||||
uint8 *p = (uint8 *)fInfo->bits + clip->top
|
||||
* fInfo->bytes_per_row + clip->left * bytesPerPixel;
|
||||
uint8 *b = (uint8 *)fBitmap->Bits()
|
||||
+ (clip->top - fInfo->window_bounds.top) * bytesPerRow
|
||||
+ (clip->left - fInfo->window_bounds.left) * bytesPerPixel;
|
||||
|
||||
for (int y = 0; y < height - 1; y++) {
|
||||
memcpy(p, b, bytesWidth);
|
||||
p += fInfo->bytes_per_row;
|
||||
b += bytesPerRow;
|
||||
}
|
||||
}
|
||||
|
||||
if (vsync)
|
||||
screen.WaitForRetrace();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::Draw(BRect updateRect)
|
||||
{
|
||||
// CALLED();
|
||||
if ((!fDirectModeEnabled || fInfo == NULL) && fBitmap)
|
||||
GLView()->DrawBitmap(fBitmap, updateRect, updateRect);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SoftwareRenderer::CopyPixelsOut(BPoint location, BBitmap *bitmap)
|
||||
{
|
||||
CALLED();
|
||||
color_space scs = fBitmap->ColorSpace();
|
||||
color_space dcs = bitmap->ColorSpace();
|
||||
|
||||
if (scs != dcs && (scs != B_RGBA32 || dcs != B_RGB32)) {
|
||||
ERROR("%s::CopyPixelsOut(): incompatible color space: %s != %s\n",
|
||||
__PRETTY_FUNCTION__, color_space_name(scs), color_space_name(dcs));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = fBitmap->Bounds();
|
||||
BRect dr = bitmap->Bounds();
|
||||
|
||||
// int32 w1 = sr.IntegerWidth();
|
||||
// int32 h1 = sr.IntegerHeight();
|
||||
// int32 w2 = dr.IntegerWidth();
|
||||
// int32 h2 = dr.IntegerHeight();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8 *ps = (uint8 *) fBitmap->Bits();
|
||||
uint8 *pd = (uint8 *) bitmap->Bits();
|
||||
uint32 *s, *d;
|
||||
uint32 y;
|
||||
for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
|
||||
s = (uint32 *)(ps + y * fBitmap->BytesPerRow());
|
||||
s += (uint32) sr.left;
|
||||
|
||||
d = (uint32 *)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* bitmap->BytesPerRow());
|
||||
d += (uint32) dr.left;
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
SoftwareRenderer::CopyPixelsIn(BBitmap *bitmap, BPoint location)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
color_space sourceCS = bitmap->ColorSpace();
|
||||
color_space destinationCS = fBitmap->ColorSpace();
|
||||
|
||||
if (sourceCS != destinationCS
|
||||
&& (sourceCS != B_RGB32 || destinationCS != B_RGBA32)) {
|
||||
ERROR("%s::CopyPixelsIn(): incompatible color space: %s != %s\n",
|
||||
__PRETTY_FUNCTION__, color_space_name(sourceCS),
|
||||
color_space_name(destinationCS));
|
||||
return B_BAD_TYPE;
|
||||
}
|
||||
|
||||
BRect sr = bitmap->Bounds();
|
||||
BRect dr = fBitmap->Bounds();
|
||||
|
||||
sr = sr & dr.OffsetBySelf(location);
|
||||
dr = sr.OffsetByCopy(-location.x, -location.y);
|
||||
|
||||
uint8 *ps = (uint8 *) bitmap->Bits();
|
||||
uint8 *pd = (uint8 *) fBitmap->Bits();
|
||||
uint32 *s, *d;
|
||||
uint32 y;
|
||||
|
||||
for (y = (uint32) sr.top; y <= (uint32) sr.bottom; y++) {
|
||||
s = (uint32 *)(ps + y * bitmap->BytesPerRow());
|
||||
s += (uint32) sr.left;
|
||||
|
||||
d = (uint32 *)(pd + (y + (uint32)(dr.top - sr.top))
|
||||
* fBitmap->BytesPerRow());
|
||||
d += (uint32) dr.left;
|
||||
|
||||
memcpy(d, s, dr.IntegerWidth() * 4);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::EnableDirectMode(bool enabled)
|
||||
{
|
||||
fDirectModeEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::DirectConnected(direct_buffer_info *info)
|
||||
{
|
||||
// CALLED();
|
||||
BAutolock lock(fInfoLocker);
|
||||
if (info) {
|
||||
if (!fInfo) {
|
||||
fInfo = (direct_buffer_info *)calloc(1,
|
||||
DIRECT_BUFFER_INFO_AREA_SIZE);
|
||||
}
|
||||
memcpy(fInfo, info, DIRECT_BUFFER_INFO_AREA_SIZE);
|
||||
} else if (fInfo) {
|
||||
free(fInfo);
|
||||
fInfo = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::FrameResized(float width, float height)
|
||||
{
|
||||
// CALLED();
|
||||
BAutolock lock(fInfoLocker);
|
||||
fNewWidth = (GLuint)width;
|
||||
fNewHeight = (GLuint)height;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SoftwareRenderer::_AllocateBitmap()
|
||||
{
|
||||
// CALLED();
|
||||
|
||||
// allocate new size of back buffer bitmap
|
||||
BAutolock lock(fInfoLocker);
|
||||
delete fBitmap;
|
||||
fBitmap = NULL;
|
||||
if (fWidth < 1 || fHeight < 1) {
|
||||
TRACE("%s: Can't allocate bitmap of %dx%d\n", __func__,
|
||||
fWidth, fHeight);
|
||||
return;
|
||||
}
|
||||
BRect rect(0.0, 0.0, fWidth, fHeight);
|
||||
fBitmap = new (std::nothrow) BBitmap(rect, fColorSpace);
|
||||
if (fBitmap == NULL) {
|
||||
TRACE("%s: Can't create bitmap!\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// debug..
|
||||
void *data = fBitmap->Bits();
|
||||
memset(data, 0xcc, fBitmap->BitsLength());
|
||||
#endif
|
||||
}
|
||||
59
src/gallium/targets/haiku-softpipe/SoftwareRenderer.h
Normal file
59
src/gallium/targets/haiku-softpipe/SoftwareRenderer.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2006-2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval, korli@users.berlios.de
|
||||
* Philippe Houdoin, philippe.houdoin@free.fr
|
||||
* Artur Wyszynski, harakash@gmail.com
|
||||
* Alexander von Gluck IV, kallisti5@unixzen.com
|
||||
*/
|
||||
#ifndef SOFTWARERENDERER_H
|
||||
#define SOFTWARERENDERER_H
|
||||
|
||||
|
||||
#include <kernel/image.h>
|
||||
|
||||
#include "GLRenderer.h"
|
||||
#include "GalliumContext.h"
|
||||
|
||||
|
||||
class SoftwareRenderer : public BGLRenderer {
|
||||
public:
|
||||
SoftwareRenderer(BGLView *view,
|
||||
ulong bgl_options,
|
||||
BGLDispatcher *dispatcher);
|
||||
virtual ~SoftwareRenderer();
|
||||
|
||||
virtual void LockGL();
|
||||
virtual void UnlockGL();
|
||||
|
||||
virtual void SwapBuffers(bool vsync = false);
|
||||
virtual void Draw(BRect updateRect);
|
||||
virtual status_t CopyPixelsOut(BPoint source, BBitmap *dest);
|
||||
virtual status_t CopyPixelsIn(BBitmap *source, BPoint dest);
|
||||
virtual void FrameResized(float width, float height);
|
||||
|
||||
virtual void EnableDirectMode(bool enabled);
|
||||
virtual void DirectConnected(direct_buffer_info *info);
|
||||
|
||||
private:
|
||||
|
||||
void _AllocateBitmap();
|
||||
|
||||
GalliumContext* fContextObj;
|
||||
BBitmap* fBitmap;
|
||||
context_id fContextID;
|
||||
|
||||
bool fDirectModeEnabled;
|
||||
direct_buffer_info* fInfo;
|
||||
BLocker fInfoLocker;
|
||||
ulong fOptions;
|
||||
GLuint fWidth;
|
||||
GLuint fHeight;
|
||||
GLuint fNewWidth;
|
||||
GLuint fNewHeight;
|
||||
color_space fColorSpace;
|
||||
};
|
||||
|
||||
#endif // SOFTPIPERENDERER_H
|
||||
39
src/gallium/targets/haiku-softpipe/SoftwareRenderer.rdef
Normal file
39
src/gallium/targets/haiku-softpipe/SoftwareRenderer.rdef
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2012, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
resource app_signature "application/x-vnd.Haiku-swpipe";
|
||||
|
||||
resource app_version {
|
||||
major = 9,
|
||||
middle = 0,
|
||||
minor = 0,
|
||||
variety = 0,
|
||||
internal = 0,
|
||||
short_info = "Software Renderer",
|
||||
long_info = "Haiku Gallium Software GL Renderer"
|
||||
};
|
||||
|
||||
resource vector_icon {
|
||||
$"6E6369660A0200140294A9FF18020014028DFFFF97058C0500020006023B10B7"
|
||||
$"37F036BA1A993D466848C719BEBE2000919292FFD5D5D5020016023900000000"
|
||||
$"000000003EE0004AE00048E0005EF884C702000203392E8D383001BAD97F3C12"
|
||||
$"8B4786BD48B8AD0D97BBFFFF7B4168DBE9FF4168DB97020002023A0C1238D099"
|
||||
$"BE44203F4BD14B38844678240DF56A7D9FE1EA064CC704016B0500090A044024"
|
||||
$"2438404C5C380A044028243C40505C3C0A042438243B5C3C5C380608BFBE4D59"
|
||||
$"4D59515957575659585560406044603C5E3A5C3CCB4FBFBA5E3ECA9DC11F564B"
|
||||
$"584A544C504C0606AF0F2F3D2F3D393D4034BF593542324130432F42364432C0"
|
||||
$"3FBC5A2F48354A2F480608AE9A22303EB5BD3AB42542B755422E412F3C29322D"
|
||||
$"32223C0204263726372538263F253E263F304430443143303C313D303C02043D"
|
||||
$"423D423C433D4A3C493D4A495049504A4F49474A484947060DAEAAAE014E445A"
|
||||
$"3456365E325E3D5D3F5A3A5542544E4D573A4E364439463342324A2242310A0A"
|
||||
$"0002020102403CA00C88888C8CC1401673C40D6544F2950A01010002403CA000"
|
||||
$"0000000000401673C40D65446CF80A08020304023EC16A0000000000003EC16A"
|
||||
$"45DD1844C6550A030105123EC16A0000000000003EC16A45DD1844C655011784"
|
||||
$"22040A040105023EC16A0000000000003EC16A45DD1844C6550A030108123EC1"
|
||||
$"6A0000000000003EC16A45DD1844C65501178422040A0503080706023EC16A00"
|
||||
$"00000000003EC16A45DD1844C6550A030206071A3EC16A0000000000003EC16A"
|
||||
$"45DD1844C65510FF0215810004178222040A060106023EC16A0000000000003E"
|
||||
$"C16A45DD1844C6550A070107023EC16A0000000000003EC16A45DD1844C655"
|
||||
};
|
||||
|
|
@ -21,5 +21,4 @@ if env['platform'] in ('haiku'):
|
|||
'bitmap_wrapper.cpp',
|
||||
]
|
||||
)
|
||||
env.Alias('ws_haiku', ws_haiku)
|
||||
Export('ws_haiku')
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue