context.c

来自「Mesa is an open-source implementation of」· C语言 代码 · 共 1,776 行 · 第 1/4 页

C
1,776
字号
 */void_mesa_copy_context( const GLcontext *src, GLcontext *dst, GLuint mask ){   if (mask & GL_ACCUM_BUFFER_BIT) {      /* OK to memcpy */      dst->Accum = src->Accum;   }   if (mask & GL_COLOR_BUFFER_BIT) {      /* OK to memcpy */      dst->Color = src->Color;   }   if (mask & GL_CURRENT_BIT) {      /* OK to memcpy */      dst->Current = src->Current;   }   if (mask & GL_DEPTH_BUFFER_BIT) {      /* OK to memcpy */      dst->Depth = src->Depth;   }   if (mask & GL_ENABLE_BIT) {      /* no op */   }   if (mask & GL_EVAL_BIT) {      /* OK to memcpy */      dst->Eval = src->Eval;   }   if (mask & GL_FOG_BIT) {      /* OK to memcpy */      dst->Fog = src->Fog;   }   if (mask & GL_HINT_BIT) {      /* OK to memcpy */      dst->Hint = src->Hint;   }   if (mask & GL_LIGHTING_BIT) {      GLuint i;      /* begin with memcpy */      dst->Light = src->Light;      /* fixup linked lists to prevent pointer insanity */      make_empty_list( &(dst->Light.EnabledList) );      for (i = 0; i < MAX_LIGHTS; i++) {         if (dst->Light.Light[i].Enabled) {            insert_at_tail(&(dst->Light.EnabledList), &(dst->Light.Light[i]));         }      }   }   if (mask & GL_LINE_BIT) {      /* OK to memcpy */      dst->Line = src->Line;   }   if (mask & GL_LIST_BIT) {      /* OK to memcpy */      dst->List = src->List;   }   if (mask & GL_PIXEL_MODE_BIT) {      /* OK to memcpy */      dst->Pixel = src->Pixel;   }   if (mask & GL_POINT_BIT) {      /* OK to memcpy */      dst->Point = src->Point;   }   if (mask & GL_POLYGON_BIT) {      /* OK to memcpy */      dst->Polygon = src->Polygon;   }   if (mask & GL_POLYGON_STIPPLE_BIT) {      /* Use loop instead of MEMCPY due to problem with Portland Group's       * C compiler.  Reported by John Stone.       */      GLuint i;      for (i = 0; i < 32; i++) {         dst->PolygonStipple[i] = src->PolygonStipple[i];      }   }   if (mask & GL_SCISSOR_BIT) {      /* OK to memcpy */      dst->Scissor = src->Scissor;   }   if (mask & GL_STENCIL_BUFFER_BIT) {      /* OK to memcpy */      dst->Stencil = src->Stencil;   }   if (mask & GL_TEXTURE_BIT) {      /* Cannot memcpy because of pointers */      _mesa_copy_texture_state(src, dst);   }   if (mask & GL_TRANSFORM_BIT) {      /* OK to memcpy */      dst->Transform = src->Transform;   }   if (mask & GL_VIEWPORT_BIT) {      /* Cannot use memcpy, because of pointers in GLmatrix _WindowMap */      dst->Viewport.X = src->Viewport.X;      dst->Viewport.Y = src->Viewport.Y;      dst->Viewport.Width = src->Viewport.Width;      dst->Viewport.Height = src->Viewport.Height;      dst->Viewport.Near = src->Viewport.Near;      dst->Viewport.Far = src->Viewport.Far;      _math_matrix_copy(&dst->Viewport._WindowMap, &src->Viewport._WindowMap);   }   /* XXX FIXME:  Call callbacks?    */   dst->NewState = _NEW_ALL;}#endif/** * Check if the given context can render into the given framebuffer * by checking visual attributes. * * Most of these tests could go away because Mesa is now pretty flexible * in terms of mixing rendering contexts with framebuffers.  As long * as RGB vs. CI mode agree, we're probably good. * * \return GL_TRUE if compatible, GL_FALSE otherwise. */static GLboolean check_compatible(const GLcontext *ctx, const GLframebuffer *buffer){   const GLvisual *ctxvis = &ctx->Visual;   const GLvisual *bufvis = &buffer->Visual;   if (ctxvis == bufvis)      return GL_TRUE;   if (ctxvis->rgbMode != bufvis->rgbMode)      return GL_FALSE;#if 0   /* disabling this fixes the fgl_glxgears pbuffer demo */   if (ctxvis->doubleBufferMode && !bufvis->doubleBufferMode)      return GL_FALSE;#endif   if (ctxvis->stereoMode && !bufvis->stereoMode)      return GL_FALSE;   if (ctxvis->haveAccumBuffer && !bufvis->haveAccumBuffer)      return GL_FALSE;   if (ctxvis->haveDepthBuffer && !bufvis->haveDepthBuffer)      return GL_FALSE;   if (ctxvis->haveStencilBuffer && !bufvis->haveStencilBuffer)      return GL_FALSE;   if (ctxvis->redMask && ctxvis->redMask != bufvis->redMask)      return GL_FALSE;   if (ctxvis->greenMask && ctxvis->greenMask != bufvis->greenMask)      return GL_FALSE;   if (ctxvis->blueMask && ctxvis->blueMask != bufvis->blueMask)      return GL_FALSE;#if 0   /* disabled (see bug 11161) */   if (ctxvis->depthBits && ctxvis->depthBits != bufvis->depthBits)      return GL_FALSE;#endif   if (ctxvis->stencilBits && ctxvis->stencilBits != bufvis->stencilBits)      return GL_FALSE;   return GL_TRUE;}/** * Do one-time initialization for the given framebuffer.  Specifically, * ask the driver for the window's current size and update the framebuffer * object to match. * Really, the device driver should totally take care of this. */static voidinitialize_framebuffer_size(GLcontext *ctx, GLframebuffer *fb){   GLuint width, height;   if (ctx->Driver.GetBufferSize) {      ctx->Driver.GetBufferSize(fb, &width, &height);      if (ctx->Driver.ResizeBuffers)         ctx->Driver.ResizeBuffers(ctx, fb, width, height);      fb->Initialized = GL_TRUE;   }}/** * Bind the given context to the given drawBuffer and readBuffer and * make it the current context for the calling thread. * We'll render into the drawBuffer and read pixels from the * readBuffer (i.e. glRead/CopyPixels, glCopyTexImage, etc). * * We check that the context's and framebuffer's visuals are compatible * and return immediately if they're not. * * \param newCtx  the new GL context. If NULL then there will be no current GL *                context. * \param drawBuffer  the drawing framebuffer * \param readBuffer  the reading framebuffer */void_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,                    GLframebuffer *readBuffer ){   if (MESA_VERBOSE & VERBOSE_API)      _mesa_debug(newCtx, "_mesa_make_current()\n");   /* Check that the context's and framebuffer's visuals are compatible.    */   if (newCtx && drawBuffer && newCtx->WinSysDrawBuffer != drawBuffer) {      if (!check_compatible(newCtx, drawBuffer)) {         _mesa_warning(newCtx,              "MakeCurrent: incompatible visuals for context and drawbuffer");         return;      }   }   if (newCtx && readBuffer && newCtx->WinSysReadBuffer != readBuffer) {      if (!check_compatible(newCtx, readBuffer)) {         _mesa_warning(newCtx,              "MakeCurrent: incompatible visuals for context and readbuffer");         return;      }   }   /* We used to call _glapi_check_multithread() here.  Now do it in drivers */   _glapi_set_context((void *) newCtx);   ASSERT(_mesa_get_current_context() == newCtx);   if (!newCtx) {      _glapi_set_dispatch(NULL);  /* none current */   }   else {      _glapi_set_dispatch(newCtx->CurrentDispatch);      if (drawBuffer && readBuffer) {	 /* TODO: check if newCtx and buffer's visual match??? */         ASSERT(drawBuffer->Name == 0);         ASSERT(readBuffer->Name == 0);         _mesa_reference_framebuffer(&newCtx->WinSysDrawBuffer, drawBuffer);         _mesa_reference_framebuffer(&newCtx->WinSysReadBuffer, readBuffer);         /*          * Only set the context's Draw/ReadBuffer fields if they're NULL          * or not bound to a user-created FBO.          */         if (!newCtx->DrawBuffer || newCtx->DrawBuffer->Name == 0) {            _mesa_reference_framebuffer(&newCtx->DrawBuffer, drawBuffer);         }         if (!newCtx->ReadBuffer || newCtx->ReadBuffer->Name == 0) {            _mesa_reference_framebuffer(&newCtx->ReadBuffer, readBuffer);         }         /* XXX only set this flag if we're really changing the draw/read          * framebuffer bindings.          */	 newCtx->NewState |= _NEW_BUFFERS;#if 1         /* We want to get rid of these lines: */#if _HAVE_FULL_GL         if (!drawBuffer->Initialized) {            initialize_framebuffer_size(newCtx, drawBuffer);         }         if (readBuffer != drawBuffer && !readBuffer->Initialized) {            initialize_framebuffer_size(newCtx, readBuffer);         }	 _mesa_resizebuffers(newCtx);#endif#else         /* We want the drawBuffer and readBuffer to be initialized by          * the driver.          * This generally means the Width and Height match the actual          * window size and the renderbuffers (both hardware and software          * based) are allocated to match.  The later can generally be          * done with a call to _mesa_resize_framebuffer().          *          * It's theoretically possible for a buffer to have zero width          * or height, but for now, assert check that the driver did what's          * expected of it.          */         ASSERT(drawBuffer->Width > 0);         ASSERT(drawBuffer->Height > 0);#endif         if (newCtx->FirstTimeCurrent) {            /* set initial viewport and scissor size now */            _mesa_set_viewport(newCtx, 0, 0,                               drawBuffer->Width, drawBuffer->Height);	    _mesa_set_scissor(newCtx, 0, 0,			      drawBuffer->Width, drawBuffer->Height );            check_context_limits(newCtx);         }      }      /* We can use this to help debug user's problems.  Tell them to set       * the MESA_INFO env variable before running their app.  Then the       * first time each context is made current we'll print some useful       * information.       */      if (newCtx->FirstTimeCurrent) {	 if (_mesa_getenv("MESA_INFO")) {	    _mesa_print_info();	 }	 newCtx->FirstTimeCurrent = GL_FALSE;      }   }}/** * Make context 'ctx' share the display lists, textures and programs * that are associated with 'ctxToShare'. * Any display lists, textures or programs associated with 'ctx' will * be deleted if nobody else is sharing them. */GLboolean_mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare){   if (ctx && ctxToShare && ctx->Shared && ctxToShare->Shared) {      struct gl_shared_state *oldSharedState = ctx->Shared;      ctx->Shared = ctxToShare->Shared;      ctx->Shared->RefCount++;      update_default_objects(ctx);      oldSharedState->RefCount--;      if (oldSharedState->RefCount == 0) {         free_shared_state(ctx, oldSharedState);      }      return GL_TRUE;   }   else {      return GL_FALSE;   }}/** * \return pointer to the current GL context for this thread. *  * Calls _glapi_get_context(). This isn't the fastest way to get the current * context.  If you need speed, see the #GET_CURRENT_CONTEXT macro in * context.h. */GLcontext *_mesa_get_current_context( void ){   return (GLcontext *) _glapi_get_context();}/** * Get context's current API dispatch table. * * It'll either be the immediate-mode execute dispatcher or the display list * compile dispatcher. *  * \param ctx GL context. * * \return pointer to dispatch_table. * * Simply returns __GLcontextRec::CurrentDispatch. */struct _glapi_table *_mesa_get_dispatch(GLcontext *ctx){   return ctx->CurrentDispatch;}/*@}*//**********************************************************************//** \name Miscellaneous functions                                     *//**********************************************************************//*@{*//** * Record an error. * * \param ctx GL context. * \param error error code. *  * Records the given error code and call the driver's dd_function_table::Error * function if defined. * * \sa * This is called via _mesa_error(). */void_mesa_record_error(GLcontext *ctx, GLenum error){   if (!ctx)      return;   if (ctx->ErrorValue == GL_NO_ERROR) {      ctx->ErrorValue = error;   }   /* Call device driver's error handler, if any.  This is used on the Mac. */   if (ctx->Driver.Error) {      ctx->Driver.Error(ctx);   }}/** * Execute glFinish(). * * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the * dd_function_table::Finish driver callback, if not NULL. */void GLAPIENTRY_mesa_Finish(void){   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);   if (ctx->Driver.Finish) {      ctx->Driver.Finish(ctx);   }}/** * Execute glFlush(). * * Calls the #ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH macro and the * dd_function_table::Flush driver callback, if not NULL. */void GLAPIENTRY_mesa_Flush(void){   GET_CURRENT_CONTEXT(ctx);   ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);   if (ctx->Driver.Flush) {      ctx->Driver.Flush(ctx);   }}/*@}*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?