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->screen = fScreen;
	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;
	}

	// Create state_tracker manager
	context->manager = hgl_create_st_manager(context);

	// Create state tracker visual
	context->stVisual = hgl_create_st_visual(fOptions);

	// Create state tracker framebuffers
	context->draw = hgl_create_st_framebuffer(context);
	context->read = hgl_create_st_framebuffer(context);

	if (!context->draw || !context->read) {
		ERROR("%s: Problem allocating framebuffer!\n", __func__);
		FREE(context->stVisual);
		return -1;
	}

	// 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;
		}

		hgl_destroy_st_visual(context->stVisual);
		FREE(context);
		return -1;
	}

	assert(!context->st->st_manager_private);
	context->st->st_manager_private = (void*)context;

	struct st_context *stContext = (struct st_context*)context->st;
	
	// Init Gallium3D Post Processing
	// TODO: no pp filters are enabled yet through postProcessEnable
	context->postProcess = pp_init(stContext->pipe, context->postProcessEnable,
		stContext->cso_context);

	context_id contextNext = -1;
	Lock();
	for (context_id i = 0; i < CONTEXT_MAX; i++) {
		if (fContext[i] == NULL) {
			fContext[i] = context;
			contextNext = i;
			break;
		}
	}
	Unlock();

	if (contextNext < 0) {
		ERROR("%s: The next context is invalid... something went wrong!\n",
			__func__);
		//st_destroy_context(context->st);
		FREE(context->stVisual);
		FREE(context);
		return -1;
	}

	TRACE("%s: context #%" B_PRIu64 " is the next available context\n",
		__func__, contextNext);

	return contextNext;
}
Esempio n. 2
0
uint64
hsp_create_layer_context(Bitmap *bitmap, int layerPlane)
{
	TRACE("%s(bitmap: %p layerPlane: %d)\n", __FUNCTION__,
		bitmap, layerPlane);
	time_t total_beg, total_end;
	time_t beg, end;
	total_beg = time(NULL);
	struct hsp_context *ctx = NULL;
	struct pipe_screen *screen = NULL;
	GLvisual *visual = NULL;
	struct pipe_context *pipe = NULL;
	uint ctxId = 0;

	if (!hsp_dev) {
		TRACE("%s> there is no hsp_dev!\n", __FUNCTION__);
		return 0;
	}

	if (layerPlane != 0) {
		TRACE("%s> layerPlane != 0\n", __FUNCTION__);
		return 0;
	}

	ctx = CALLOC_STRUCT(hsp_context);
	if (!ctx) {
		TRACE("%s> can't alloc hsp_context!\n", __FUNCTION__);
		goto no_ctx;
	}

	ctx->bitmap = bitmap;
	ctx->colorSpace = get_bitmap_color_space(bitmap);
	ctx->draw = NULL;
	ctx->read = NULL;

	screen = hsp_dev->screen;

#ifdef DEBUG
    /* Unwrap screen */
    if (hsp_dev->trace_running)
        screen = trace_screen(screen)->screen;
#endif

	ulong options = hsp_dev->options;

	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 GLint depth		= (options & BGL_DEPTH) ? 24 : 0;
	const GLint stencil		= (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum		= 0;					// (options & BGL_ACCUM) ? 16 : 0;
	const GLint index		= 0;					// (options & BGL_INDEX) ? 32 : 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("index       :\t%d\n", index);
	TRACE("red         :\t%d\n", red);
	TRACE("green       :\t%d\n", green);
	TRACE("blue        :\t%d\n", blue);
	TRACE("alpha       :\t%d\n", alpha);

	visual = _mesa_create_visual(
		rgbFlag, dblFlag, stereoFlag, red, green, blue, alpha, index, depth,
		stencil, accum, accum, accum, alpha ? accum : 0, 1);

	TRACE("depthBits   :\t%d\n", visual->depthBits);
	TRACE("stencilBits :\t%d\n", visual->stencilBits);

	if (!visual) {
		TRACE("%s> can't create mesa visual!\n", __FUNCTION__);
		goto no_ctx_id;
	}

	pipe = hsp_dev->hsp_winsys->create_context(screen);

	if (!pipe) {
		TRACE("%s> can't create pipe!\n", __FUNCTION__);
		goto no_pipe;
	}

#ifdef DEBUG
    if (hsp_dev->trace_running)
        pipe = trace_context_create(hsp_dev->screen, pipe);
#endif

	assert(!pipe->priv);
	pipe->priv = bitmap;

	ctx->st = st_create_context(pipe, visual, NULL);
	if (!ctx->st) {
		TRACE("%s> can't create mesa statetracker context!\n",
			__FUNCTION__);
		goto no_st_ctx;
	}

	ctx->st->ctx->DriverCtx = ctx;

	pipe_mutex_lock(hsp_dev->mutex);
	uint64 i;
	for (i = 0; i < HSP_CONTEXT_MAX; i++) {
		if (hsp_dev->ctx_array[i].ctx == NULL) {
			hsp_dev->ctx_array[i].ctx = ctx;
			ctxId = i + 1;
			break;
		}
	}
	pipe_mutex_unlock(hsp_dev->mutex);

	if (ctxId != 0)
		return ctxId;

no_ctx_id:
	TRACE("%s> no_ctx_id!\n", __FUNCTION__);
    _mesa_destroy_visual(visual);
    st_destroy_context(ctx->st);
    goto no_pipe; /* st_context_destroy already destroy pipe */
no_st_ctx:
	TRACE("%s> no_st_ctx!\n", __FUNCTION__);
    pipe->destroy(pipe);
no_pipe:
	TRACE("%s> no_pipe!\n", __FUNCTION__);
    FREE(ctx);
no_ctx:
	TRACE("%s> no_ctx!\n", __FUNCTION__);
    return 0;
}
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			= (fOptions & BGL_ACCUM) ? 16 : 0;
	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", 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;
	}

	assert(!context->st->st_manager_private);
	context->st->st_manager_private = (void*)context;

	struct st_context *stContext = (struct st_context*)context->st;
	
	stContext->ctx->Driver.Viewport = hgl_viewport;

	// Init Gallium3D Post Processing
	// TODO: no pp filters are enabled yet through postProcessEnable
	context->postProcess = pp_init(stContext->pipe, context->postProcessEnable,
		stContext->cso_context);

	context_id contextNext = -1;
	Lock();
	for (context_id i = 0; i < CONTEXT_MAX; i++) {
		if (fContext[i] == NULL) {
			fContext[i] = context;
			contextNext = i;
			break;
		}
	}
	Unlock();

	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;
}