예제 #1
0
파일: swrast.c 프로젝트: nikai3d/mesa
static GLboolean
dri_create_buffer(__DRIscreen * sPriv,
		  __DRIdrawable * dPriv,
		  const struct gl_config * visual, GLboolean isPixmap)
{
    struct dri_drawable *drawable = NULL;
    struct gl_framebuffer *fb;
    struct swrast_renderbuffer *frontrb, *backrb;

    TRACE;

    drawable = CALLOC_STRUCT(dri_drawable);
    if (drawable == NULL)
	goto drawable_fail;

    dPriv->driverPrivate = drawable;
    drawable->dPriv = dPriv;

    drawable->row = malloc(MAX_WIDTH * 4);
    if (drawable->row == NULL)
	goto drawable_fail;

    fb = &drawable->Base;

    /* basic framebuffer setup */
    _mesa_initialize_window_framebuffer(fb, visual);

    /* add front renderbuffer */
    frontrb = swrast_new_renderbuffer(visual, GL_TRUE);
    _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &frontrb->Base);

    /* add back renderbuffer */
    if (visual->doubleBufferMode) {
	backrb = swrast_new_renderbuffer(visual, GL_FALSE);
	_mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &backrb->Base);
    }

    /* add software renderbuffers */
    _mesa_add_soft_renderbuffers(fb,
				 GL_FALSE, /* color */
				 visual->haveDepthBuffer,
				 visual->haveStencilBuffer,
				 visual->haveAccumBuffer,
				 GL_FALSE, /* alpha */
				 GL_FALSE /* aux bufs */);

    return GL_TRUE;

drawable_fail:

    if (drawable)
	free(drawable->row);

    FREE(drawable);

    return GL_FALSE;
}
예제 #2
0
static EGLSurface
fbCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
{
   fbSurface *surf;

   surf = (fbSurface *) calloc(1, sizeof(fbSurface));
   if (!surf) {
      return EGL_NO_SURFACE;
   }

   if (_eglInitPbufferSurface(&surf->Base, drv, dpy, config, attrib_list) == EGL_NO_SURFACE) {
      free(surf);
      return EGL_NO_SURFACE;
   }

   /* create software-based pbuffer */
   {
      GLcontext *ctx = NULL; /* this _should_ be OK */
      GLvisual vis;
      _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
      assert(conf); /* bad config should be caught earlier */
      _eglConfigToContextModesRec(conf, &vis);

      surf->mesa_framebuffer = _mesa_create_framebuffer(&vis);
      _mesa_add_soft_renderbuffers(surf->mesa_framebuffer,
                                   GL_TRUE, /* color bufs */
                                   vis.haveDepthBuffer,
                                   vis.haveStencilBuffer,
                                   vis.haveAccumBuffer,
                                   GL_FALSE, /* alpha */
                                   GL_FALSE /* aux */ );

      /* set pbuffer/framebuffer size */
      _mesa_resize_framebuffer(ctx, surf->mesa_framebuffer,
                               surf->Base.Width, surf->Base.Height);
   }

   return surf->Base.Handle;
}
예제 #3
0
/**
 * Create a drawing surface which can be directly displayed on a screen.
 */
static EGLSurface
fbCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
                          const EGLint *attrib_list)
{
   _EGLConfig *config = _eglLookupConfig(drv, dpy, cfg);
   fbDisplay *display = Lookup_fbDisplay(dpy);
   fbSurface *surface;
   EGLSurface surf;
   GLvisual vis;
   GLcontext *ctx = NULL; /* this should be OK */
   int origin, bytesPerPixel;
   int width, height, stride;
   
   surface = (fbSurface *) malloc(sizeof(*surface));
   if (!surface) {
      return EGL_NO_SURFACE;
   }

   /* init base class, error check, etc. */
   surf = _eglInitScreenSurface(&surface->Base, drv, dpy, cfg, attrib_list);
   if (surf == EGL_NO_SURFACE) {
      free(surface);
      return EGL_NO_SURFACE;
   }

   /* convert EGLConfig to GLvisual */
   _eglConfigToContextModesRec(config, &vis);

   /* create Mesa framebuffer */
   surface->mesa_framebuffer = _mesa_create_framebuffer(&vis);
   if (!surface->mesa_framebuffer) {
      free(surface);
      _eglRemoveSurface(&surface->Base);
      return EGL_NO_SURFACE;
   }

   width = surface->Base.Width;
   height = surface->Base.Height;
   bytesPerPixel = vis.rgbBits / 8;
   stride = width * bytesPerPixel;
   origin = 0;

   /* front color renderbuffer */
   {
      driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, display->pFB,
                                                bytesPerPixel,
                                                origin, stride, NULL);
      fbSetSpanFunctions(drb, &vis);
      _mesa_add_renderbuffer(surface->mesa_framebuffer,
                             BUFFER_FRONT_LEFT, &drb->Base);
   }

   /* back color renderbuffer */
   if (vis.doubleBufferMode) {
      GLubyte *backBuf = _mesa_malloc(stride * height);
      driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA, backBuf,
                                                bytesPerPixel,
                                                origin, stride, NULL);
      fbSetSpanFunctions(drb, &vis);
      _mesa_add_renderbuffer(surface->mesa_framebuffer,
                             BUFFER_BACK_LEFT, &drb->Base);
   }

   /* other renderbuffers- software based */
   _mesa_add_soft_renderbuffers(surface->mesa_framebuffer,
                                GL_FALSE, /* color */
                                vis.haveDepthBuffer,
                                vis.haveStencilBuffer,
                                vis.haveAccumBuffer,
                                GL_FALSE, /* alpha */
                                GL_FALSE /* aux */);
   
   _mesa_resize_framebuffer(ctx, surface->mesa_framebuffer, width, height);

   return surf;
}
예제 #4
0
/*
 * New in Mesa 3.5
 *
 * Create context and specify size of ancillary buffers.
 */
GLAPI OSMesaContext GLAPIENTRY
OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
                        GLint accumBits, OSMesaContext sharelist )
{
   OSMesaContext osmesa;
   struct dd_function_table functions;
   GLint rind, gind, bind, aind;
   GLint indexBits = 0, redBits = 0, greenBits = 0, blueBits = 0, alphaBits =0;
   GLboolean rgbmode;

   rind = gind = bind = aind = 0;
   if (format==OSMESA_COLOR_INDEX) {
      indexBits = 8;
      rgbmode = GL_FALSE;
   }
   else if (format==OSMESA_RGBA) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      rind = 0;
      gind = 1;
      bind = 2;
      aind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_BGRA) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      bind = 0;
      gind = 1;
      rind = 2;
      aind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_ARGB) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = CHAN_BITS;
      aind = 0;
      rind = 1;
      gind = 2;
      bind = 3;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_RGB) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 0;
      gind = 1;
      bind = 2;
      rgbmode = GL_TRUE;
   }
   else if (format==OSMESA_BGR) {
      indexBits = 0;
      redBits = CHAN_BITS;
      greenBits = CHAN_BITS;
      blueBits = CHAN_BITS;
      alphaBits = 0;
      rind = 2;
      gind = 1;
      bind = 0;
      rgbmode = GL_TRUE;
   }
#if CHAN_TYPE == GL_UNSIGNED_BYTE
   else if (format==OSMESA_RGB_565) {
      indexBits = 0;
      redBits = 5;
      greenBits = 6;
      blueBits = 5;
      alphaBits = 0;
      rind = 0; /* not used */
      gind = 0;
      bind = 0;
      rgbmode = GL_TRUE;
   }
#endif
   else {
      return NULL;
   }

   osmesa = (OSMesaContext) CALLOC_STRUCT(osmesa_context);
   if (osmesa) {
      osmesa->gl_visual = _mesa_create_visual( rgbmode,
                                               GL_FALSE,    /* double buffer */
                                               GL_FALSE,    /* stereo */
                                               redBits,
                                               greenBits,
                                               blueBits,
                                               alphaBits,
                                               indexBits,
                                               depthBits,
                                               stencilBits,
                                               accumBits,
                                               accumBits,
                                               accumBits,
                                               alphaBits ? accumBits : 0,
                                               1            /* num samples */
                                               );
      if (!osmesa->gl_visual) {
         FREE(osmesa);
         return NULL;
      }

      /* Initialize device driver function table */
      _mesa_init_driver_functions(&functions);
      /* override with our functions */
      functions.GetString = get_string;
      functions.UpdateState = osmesa_update_state;
      functions.GetBufferSize = get_buffer_size;

      if (!_mesa_initialize_context(&osmesa->mesa,
                                    osmesa->gl_visual,
                                    sharelist ? &sharelist->mesa
                                              : (GLcontext *) NULL,
                                    &functions, (void *) osmesa)) {
         _mesa_destroy_visual( osmesa->gl_visual );
         FREE(osmesa);
         return NULL;
      }

      _mesa_enable_sw_extensions(&(osmesa->mesa));
      _mesa_enable_1_3_extensions(&(osmesa->mesa));
      _mesa_enable_1_4_extensions(&(osmesa->mesa));
      _mesa_enable_1_5_extensions(&(osmesa->mesa));

      osmesa->gl_buffer = _mesa_create_framebuffer(osmesa->gl_visual);
      if (!osmesa->gl_buffer) {
         _mesa_destroy_visual( osmesa->gl_visual );
         _mesa_free_context_data( &osmesa->mesa );
         FREE(osmesa);
         return NULL;
      }

      /* create front color buffer in user-provided memory (no back buffer) */
      _mesa_add_renderbuffer(osmesa->gl_buffer, BUFFER_FRONT_LEFT,
                             new_osmesa_renderbuffer(format));
      _mesa_add_soft_renderbuffers(osmesa->gl_buffer,
                                   GL_FALSE, /* color */
                                   osmesa->gl_visual->haveDepthBuffer,
                                   osmesa->gl_visual->haveStencilBuffer,
                                   osmesa->gl_visual->haveAccumBuffer,
                                   GL_FALSE, /* alpha */
                                   GL_FALSE /* aux */ );

      osmesa->format = format;
      osmesa->buffer = NULL;
      osmesa->width = 0;
      osmesa->height = 0;
      osmesa->userRowLength = 0;
      osmesa->rowlength = 0;
      osmesa->yup = GL_TRUE;
      osmesa->rInd = rind;
      osmesa->gInd = gind;
      osmesa->bInd = bind;
      osmesa->aInd = aind;

      /* Initialize the software rasterizer and helper modules. */
      {
	 GLcontext *ctx = &osmesa->mesa;
         SWcontext *swrast;
         TNLcontext *tnl;

	 if (!_swrast_CreateContext( ctx ) ||
             !_ac_CreateContext( ctx ) ||
             !_tnl_CreateContext( ctx ) ||
             !_swsetup_CreateContext( ctx )) {
            _mesa_destroy_visual(osmesa->gl_visual);
            _mesa_free_context_data(ctx);
            _mesa_free(osmesa);
            return NULL;
         }
	
	 _swsetup_Wakeup( ctx );

         /* use default TCL pipeline */
         tnl = TNL_CONTEXT(ctx);
         tnl->Driver.RunPipeline = _tnl_run_pipeline;

         /* Extend the software rasterizer with our optimized line and triangle
          * drawing functions.
          */
         swrast = SWRAST_CONTEXT( ctx );
         swrast->choose_line = osmesa_choose_line;
         swrast->choose_triangle = osmesa_choose_triangle;
      }
   }
   return osmesa;
}
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options,
	BGLDispatcher* dispatcher)
	: BGLRenderer(view, options, dispatcher),
	fBitmap(NULL),
	fDirectModeEnabled(false),
	fInfo(NULL),
	fInfoLocker("info locker"),
	fContext(NULL),
	fVisual(NULL),
	fFrameBuffer(NULL),
	fFrontRenderBuffer(NULL),
	fBackRenderBuffer(NULL),
	fColorSpace(B_NO_COLOR_SPACE)
{
	CALLED();

	fClearColor[BE_RCOMP] = 0;
	fClearColor[BE_GCOMP] = 0;
	fClearColor[BE_BCOMP] = 0;
	fClearColor[BE_ACOMP] = 0;

	fClearIndex = 0;

	fColorSpace = BScreen(GLView()->Window()).ColorSpace();

	// We force single buffering for the time being
	options &= ~BGL_DOUBLE;

	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) ? 16 : 0;
	const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum = (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;

	fOptions = options; // | BGL_INDIRECT;
	struct dd_function_table functions;

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

	// Initialize device driver function table
	_mesa_init_driver_functions(&functions);

	functions.GetString 	= _GetString;
	functions.UpdateState 	= _UpdateState;
	functions.GetBufferSize = NULL;
	functions.Error			= _Error;
	functions.Viewport		= _Viewport;
	functions.Flush			= _Flush;

	// create core context
#if HAIKU_MESA_VER <= 708
	fContext = _mesa_create_context(fVisual, NULL, &functions, this);
#else
	fContext = _mesa_create_context(API_OPENGL, fVisual, NULL,
		&functions, this);
#endif

	if (!fContext) {
		ERROR("%s: Failed to create Mesa context!\n", __func__);
		_mesa_destroy_visual(fVisual);
		return;
	}

	/* Initialize the software rasterizer and helper modules. */
	_swrast_CreateContext(fContext);
	_vbo_CreateContext(fContext);
	_tnl_CreateContext(fContext);
	_swsetup_CreateContext(fContext);
	_swsetup_Wakeup(fContext);

	// Use default TCL pipeline
	TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline;

	_mesa_meta_init(fContext);
	_mesa_enable_sw_extensions(fContext);
	_mesa_enable_1_3_extensions(fContext);
	_mesa_enable_1_4_extensions(fContext);
	_mesa_enable_1_5_extensions(fContext);
	_mesa_enable_2_0_extensions(fContext);
	_mesa_enable_2_1_extensions(fContext);

	// create core framebuffer
	fFrameBuffer = (struct msr_framebuffer*)calloc(1,
		sizeof(*fFrameBuffer));
	if (fFrameBuffer == NULL) {
		ERROR("%s: Unable to calloc GL FrameBuffer!\n", __func__);
		_mesa_destroy_visual(fVisual);
		return;
	}
	_mesa_initialize_window_framebuffer(&fFrameBuffer->base, fVisual);

	// Setup front render buffer
	fFrontRenderBuffer = _NewRenderBuffer(true);
	if (fFrontRenderBuffer == NULL) {
		ERROR("%s: FrontRenderBuffer is requested but unallocated!\n",
			__func__);
		_mesa_destroy_visual(fVisual);
		free(fFrameBuffer);
		return;
	}
	_mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_FRONT_LEFT,
		&fFrontRenderBuffer->base);

	// Setup back render buffer (if requested)
	if (fVisual->doubleBufferMode) {
		fBackRenderBuffer = _NewRenderBuffer(false);
		if (fBackRenderBuffer == NULL) {
			ERROR("%s: BackRenderBuffer is requested but unallocated!\n",
				__func__);
			_mesa_destroy_visual(fVisual);
			free(fFrameBuffer);
			return;
		}
		_mesa_add_renderbuffer(&fFrameBuffer->base, BUFFER_BACK_LEFT,
			&fBackRenderBuffer->base);
	}

#if HAIKU_MESA_VER >= 709
	// New Mesa
	_swrast_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
#else
	// Old Mesa
	_mesa_add_soft_renderbuffers(&fFrameBuffer->base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);
#endif

	BRect bounds = view->Bounds();
	fWidth = fNewWidth = (GLint)bounds.Width();
	fHeight = fNewHeight = (GLint)bounds.Height();

	// some stupid applications (Quake2) don't even think about calling LockGL()
	// before using glGetString and its glGet*() friends...
	// so make sure there is at least a valid context.

	if (!_mesa_get_current_context()) {
		LockGL();
		// not needed, we don't have a looper yet: UnlockLooper();
	}
}
예제 #6
0
/* Create and initialize the Mesa and driver specific pixmap buffer
 * data.
 */
static GLboolean
fbCreateBuffer( __DRIscreenPrivate *driScrnPriv,
		__DRIdrawablePrivate *driDrawPriv,
		const __GLcontextModes *mesaVis,
		GLboolean isPixmap )
{
   struct gl_framebuffer *mesa_framebuffer;
   
   if (isPixmap) {
      return GL_FALSE; /* not implemented */
   }
   else {
      const GLboolean swDepth = mesaVis->depthBits > 0;
      const GLboolean swAlpha = mesaVis->alphaBits > 0;
      const GLboolean swAccum = mesaVis->accumRedBits > 0;
      const GLboolean swStencil = mesaVis->stencilBits > 0;
      
      mesa_framebuffer = _mesa_create_framebuffer(mesaVis);
      if (!mesa_framebuffer)
         return 0;

      /* XXX double-check these parameters (bpp vs cpp, etc) */
      {
         driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
                                                   driScrnPriv->pFB,
                                                   driScrnPriv->fbBPP / 8,
                                                   driScrnPriv->fbOrigin,
                                                   driScrnPriv->fbStride,
                                                   driDrawPriv);
         fbSetSpanFunctions(drb, mesaVis);
         _mesa_add_renderbuffer(mesa_framebuffer,
                                BUFFER_FRONT_LEFT, &drb->Base);
      }
      if (mesaVis->doubleBufferMode) {
         /* XXX what are the correct origin/stride values? */
         GLvoid *backBuf = _mesa_malloc(driScrnPriv->fbStride
                                        * driScrnPriv->fbHeight);
         driRenderbuffer *drb = driNewRenderbuffer(GL_RGBA,
                                                   backBuf,
                                                   driScrnPriv->fbBPP /8,
                                                   driScrnPriv->fbOrigin,
                                                   driScrnPriv->fbStride,
                                                   driDrawPriv);
         fbSetSpanFunctions(drb, mesaVis);
         _mesa_add_renderbuffer(mesa_framebuffer,
                                BUFFER_BACK_LEFT, &drb->Base);
      }

      _mesa_add_soft_renderbuffers(mesa_framebuffer,
                                   GL_FALSE, /* color */
                                   swDepth,
                                   swStencil,
                                   swAccum,
                                   swAlpha, /* or always zero? */
                                   GL_FALSE /* aux */);
      
      driDrawPriv->driverPrivate = mesa_framebuffer;

      return 1;
   }
}
예제 #7
0
GLFBDevBufferPtr
glFBDevCreateBuffer( const struct fb_fix_screeninfo *fixInfo,
                     const struct fb_var_screeninfo *varInfo,
                     const GLFBDevVisualPtr visual,
                     void *frontBuffer, void *backBuffer, size_t size )
{
   struct GLFBDevRenderbufferRec *frontrb, *backrb;
   GLFBDevBufferPtr buf;

   ASSERT(visual);
   ASSERT(frontBuffer);
   ASSERT(size > 0);

   /* this is to update the visual if there was a resize and the
      buffer is created again */
   visual->var = *varInfo;
   visual->fix = *fixInfo;

   if (visual->fix.visual != fixInfo->visual ||
       visual->fix.type != fixInfo->type ||
       visual->var.bits_per_pixel != varInfo->bits_per_pixel ||
       visual->var.grayscale != varInfo->grayscale ||
       visual->var.red.offset != varInfo->red.offset ||
       visual->var.green.offset != varInfo->green.offset ||
       visual->var.blue.offset != varInfo->blue.offset ||
       visual->var.transp.offset != varInfo->transp.offset) {
      /* visual mismatch! */
      return NULL;
   }

   buf = CALLOC_STRUCT(GLFBDevBufferRec);
   if (!buf)
      return NULL;

   /* basic framebuffer setup */
   _mesa_initialize_window_framebuffer(&buf->glframebuffer, &visual->glvisual);
   /* add front renderbuffer */
   frontrb = new_glfbdev_renderbuffer(frontBuffer, visual);
   _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_FRONT_LEFT,
                          &frontrb->Base);
   /* add back renderbuffer */
   if (visual->glvisual.doubleBufferMode) {
      const int malloced = !backBuffer;
      if (malloced) {
         /* malloc a back buffer */
         backBuffer = malloc(size);
         if (!backBuffer) {
            _mesa_free_framebuffer_data(&buf->glframebuffer);
            free(buf);
            return NULL;
         }
      }

      backrb = new_glfbdev_renderbuffer(backBuffer, visual);
      if (!backrb) {
         /* out of mem */
         return NULL;
      }
      backrb->mallocedBuffer = malloced;

      _mesa_add_renderbuffer(&buf->glframebuffer, BUFFER_BACK_LEFT,
                             &backrb->Base);
   }
   /* add software renderbuffers */
   _mesa_add_soft_renderbuffers(&buf->glframebuffer,
                                GL_FALSE, /* color */
                                visual->glvisual.haveDepthBuffer,
                                visual->glvisual.haveStencilBuffer,
                                visual->glvisual.haveAccumBuffer,
                                GL_FALSE, /* alpha */
                                GL_FALSE /* aux bufs */);

   buf->fix = *fixInfo;   /* struct assignment */
   buf->var = *varInfo;   /* struct assignment */
   buf->visual = visual;  /* ptr assignment */
   buf->size = size;
   buf->bytesPerPixel = visual->var.bits_per_pixel / 8;

   return buf;
}
예제 #8
0
MesaSoftwareRenderer::MesaSoftwareRenderer(BGLView* view, ulong options,
		BGLDispatcher* dispatcher)
	: BGLRenderer(view, options, dispatcher),
	fBitmap(NULL),
	fDirectModeEnabled(false),
	fInfo(NULL),
	fInfoLocker("info locker"),
	fContext(NULL),
	fVisual(NULL),
	fFrameBuffer(NULL),
	fFrontRenderBuffer(NULL),
	fBackRenderBuffer(NULL),
	fColorSpace(B_NO_COLOR_SPACE)
{
	CALLED();

	fClearColor[BE_RCOMP] = 0;
	fClearColor[BE_GCOMP] = 0;
	fClearColor[BE_BCOMP] = 0;
	fClearColor[BE_ACOMP] = 0;

	fClearIndex = 0;

	fColorSpace = BScreen(GLView()->Window()).ColorSpace();

	// We force single buffering for the time being
	//options &= !BGL_DOUBLE;

	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) ? 16 : 0;
	const GLint stencil = (options & BGL_STENCIL) ? 8 : 0;
	const GLint accum = (options & BGL_ACCUM) ? 16 : 0;
	const GLint index = (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;

	fOptions = options; // | BGL_INDIRECT;
	struct dd_function_table functions;

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

	// Initialize device driver function table
	_mesa_init_driver_functions(&functions);

	functions.GetString 	= _GetString;
	functions.UpdateState 	= _UpdateState;
	functions.GetBufferSize = NULL;
	functions.Error			= _Error;
	functions.Viewport		= _Viewport;
	functions.Flush			= _Flush;

	// create core context
	fContext = _mesa_create_context(fVisual, NULL, &functions, this);
	if (!fContext) {
		_mesa_destroy_visual(fVisual);
		return;
	}

	/* Initialize the software rasterizer and helper modules. */
	_swrast_CreateContext(fContext);
	_vbo_CreateContext(fContext);
	_tnl_CreateContext(fContext);
	_swsetup_CreateContext(fContext);
	_swsetup_Wakeup(fContext);

	// Use default TCL pipeline
	TNL_CONTEXT(fContext)->Driver.RunPipeline = _tnl_run_pipeline;

	_mesa_enable_sw_extensions(fContext);
	_mesa_enable_1_3_extensions(fContext);
	_mesa_enable_1_4_extensions(fContext);
	_mesa_enable_1_5_extensions(fContext);
	_mesa_enable_2_0_extensions(fContext);
	_mesa_enable_2_1_extensions(fContext);

	// create core framebuffer
	fFrameBuffer = (struct msr_framebuffer*)_mesa_calloc(
		sizeof(*fFrameBuffer));
	_mesa_initialize_framebuffer(&fFrameBuffer->Base, fVisual);

	fFrontRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc(
		sizeof(*fFrontRenderBuffer));
	_mesa_init_renderbuffer(&fFrontRenderBuffer->Base, 0);

	fFrontRenderBuffer->Base.AllocStorage = _FrontRenderbufferStorage;
	fFrontRenderBuffer->Base.Data = NULL;
	fFrontRenderBuffer->Base.InternalFormat = GL_RGBA;
	fFrontRenderBuffer->Base._BaseFormat = GL_RGBA;
	fFrontRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE;
	fFrontRenderBuffer->Base.RedBits   = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.BlueBits  = 8 * sizeof(GLubyte);
	fFrontRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte);
	_SetSpanFuncs(fFrontRenderBuffer, fColorSpace);
	_mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_FRONT_LEFT,
		&fFrontRenderBuffer->Base);

	if (dblFlag) {
		fBackRenderBuffer = (struct msr_renderbuffer*)_mesa_calloc(
			sizeof(*fBackRenderBuffer));
		_mesa_init_renderbuffer(&fBackRenderBuffer->Base, 0);

		fBackRenderBuffer->Base.AllocStorage = _BackRenderbufferStorage;
		fBackRenderBuffer->Base.Data = NULL;
		fBackRenderBuffer->Base.Delete = _DeleteBackBuffer;
		fBackRenderBuffer->Base.InternalFormat = GL_RGBA;
		fBackRenderBuffer->Base._BaseFormat = GL_RGBA;
		fBackRenderBuffer->Base.DataType = GL_UNSIGNED_BYTE;
		fBackRenderBuffer->Base.RedBits   = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.GreenBits = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.BlueBits  = 8 * sizeof(GLubyte);
		fBackRenderBuffer->Base.AlphaBits = 8 * sizeof(GLubyte);
		_SetSpanFuncs(fBackRenderBuffer, fColorSpace);
		_mesa_add_renderbuffer(&fFrameBuffer->Base, BUFFER_BACK_LEFT,
			&fBackRenderBuffer->Base);
	}

	_mesa_add_soft_renderbuffers(&fFrameBuffer->Base, GL_FALSE,
		fVisual->haveDepthBuffer, fVisual->haveStencilBuffer,
		fVisual->haveAccumBuffer, alphaFlag, GL_FALSE);

	BRect bounds = view->Bounds();
	fWidth = fNewWidth = (GLint)bounds.Width();
	fHeight = fNewHeight = (GLint)bounds.Height();

	// some stupid applications (Quake2) don't even think about calling LockGL()
	// before using glGetString and its glGet*() friends...
	// so make sure there is at least a valid context.

	if (!_mesa_get_current_context()) {
		LockGL();
		// not needed, we don't have a looper yet: UnlockLooper();
	}
}