⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intel_buffers.c

📁 Mesa is an open-source implementation of the OpenGL specification - a system for rendering interacti
💻 C
📖 第 1 页 / 共 3 页
字号:
/************************************************************************** *  * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. * All Rights Reserved. *  * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: *  * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *  **************************************************************************/#include "intel_screen.h"#include "intel_context.h"#include "intel_blit.h"#include "intel_buffers.h"#include "intel_chipset.h"#include "intel_depthstencil.h"#include "intel_fbo.h"#include "intel_regions.h"#include "intel_batchbuffer.h"#include "intel_reg.h"#include "context.h"#include "utils.h"#include "drirenderbuffer.h"#include "framebuffer.h"#include "swrast/swrast.h"#include "vblank.h"#include "i915_drm.h"/* This block can be removed when libdrm >= 2.3.1 is required */#ifndef DRM_IOCTL_I915_FLIP#define DRM_VBLANK_FLIP 0x8000000typedef struct drm_i915_flip {   int pipes;} drm_i915_flip_t;#undef DRM_IOCTL_I915_FLIP#define DRM_IOCTL_I915_FLIP DRM_IOW(DRM_COMMAND_BASE + DRM_I915_FLIP, \				    drm_i915_flip_t)#endif#define FILE_DEBUG_FLAG DEBUG_BLIT/** * XXX move this into a new dri/common/cliprects.c file. */GLbooleanintel_intersect_cliprects(drm_clip_rect_t * dst,                          const drm_clip_rect_t * a,                          const drm_clip_rect_t * b){   GLint bx = b->x1;   GLint by = b->y1;   GLint bw = b->x2 - bx;   GLint bh = b->y2 - by;   if (bx < a->x1)      bw -= a->x1 - bx, bx = a->x1;   if (by < a->y1)      bh -= a->y1 - by, by = a->y1;   if (bx + bw > a->x2)      bw = a->x2 - bx;   if (by + bh > a->y2)      bh = a->y2 - by;   if (bw <= 0)      return GL_FALSE;   if (bh <= 0)      return GL_FALSE;   dst->x1 = bx;   dst->y1 = by;   dst->x2 = bx + bw;   dst->y2 = by + bh;   return GL_TRUE;}/** * Return pointer to current color drawing region, or NULL. */struct intel_region *intel_drawbuf_region(struct intel_context *intel){   struct intel_renderbuffer *irbColor =      intel_renderbuffer(intel->ctx.DrawBuffer->_ColorDrawBuffers[0]);   if (irbColor)      return irbColor->region;   else      return NULL;}/** * Return pointer to current color reading region, or NULL. */struct intel_region *intel_readbuf_region(struct intel_context *intel){   struct intel_renderbuffer *irb      = intel_renderbuffer(intel->ctx.ReadBuffer->_ColorReadBuffer);   if (irb)      return irb->region;   else      return NULL;}/** * Update the following fields for rendering to a user-created FBO: *   intel->numClipRects *   intel->pClipRects *   intel->drawX *   intel->drawY */static voidintelSetRenderbufferClipRects(struct intel_context *intel){   assert(intel->ctx.DrawBuffer->Width > 0);   assert(intel->ctx.DrawBuffer->Height > 0);   intel->fboRect.x1 = 0;   intel->fboRect.y1 = 0;   intel->fboRect.x2 = intel->ctx.DrawBuffer->Width;   intel->fboRect.y2 = intel->ctx.DrawBuffer->Height;   intel->numClipRects = 1;   intel->pClipRects = &intel->fboRect;   intel->drawX = 0;   intel->drawY = 0;}/** * As above, but for rendering to front buffer of a window. * \sa intelSetRenderbufferClipRects */static voidintelSetFrontClipRects(struct intel_context *intel){   __DRIdrawablePrivate *dPriv = intel->driDrawable;   if (!dPriv)      return;   intel->numClipRects = dPriv->numClipRects;   intel->pClipRects = dPriv->pClipRects;   intel->drawX = dPriv->x;   intel->drawY = dPriv->y;}/** * As above, but for rendering to back buffer of a window. */static voidintelSetBackClipRects(struct intel_context *intel){   __DRIdrawablePrivate *dPriv = intel->driDrawable;   struct intel_framebuffer *intel_fb;   if (!dPriv)      return;   intel_fb = dPriv->driverPrivate;   if (intel_fb->pf_active || dPriv->numBackClipRects == 0) {      /* use the front clip rects */      intel->numClipRects = dPriv->numClipRects;      intel->pClipRects = dPriv->pClipRects;      intel->drawX = dPriv->x;      intel->drawY = dPriv->y;   }   else {      /* use the back clip rects */      intel->numClipRects = dPriv->numBackClipRects;      intel->pClipRects = dPriv->pBackClipRects;      intel->drawX = dPriv->backX;      intel->drawY = dPriv->backY;   }}static voidintelUpdatePageFlipping(struct intel_context *intel,			GLint areaA, GLint areaB){   __DRIdrawablePrivate *dPriv = intel->driDrawable;   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;   GLboolean pf_active;   GLint pf_planes;   /* Update page flipping info */   pf_planes = 0;   if (areaA > 0)      pf_planes |= 1;   if (areaB > 0)      pf_planes |= 2;   intel_fb->pf_current_page = (intel->sarea->pf_current_page >>				(intel_fb->pf_planes & 0x2)) & 0x3;   intel_fb->pf_num_pages = intel->intelScreen->third.handle ? 3 : 2;   pf_active = pf_planes && (pf_planes & intel->sarea->pf_active) == pf_planes;   if (INTEL_DEBUG & DEBUG_LOCK)      if (pf_active != intel_fb->pf_active)	 _mesa_printf("%s - Page flipping %sactive\n", __progname,		      pf_active ? "" : "in");   if (pf_active) {      /* Sync pages between planes if flipping on both at the same time */      if (pf_planes == 0x3 && pf_planes != intel_fb->pf_planes &&	  (intel->sarea->pf_current_page & 0x3) !=	  (((intel->sarea->pf_current_page) >> 2) & 0x3)) {	 drm_i915_flip_t flip;	 if (intel_fb->pf_current_page ==	     (intel->sarea->pf_current_page & 0x3)) {	    /* XXX: This is ugly, but emitting two flips 'in a row' can cause	     * lockups for unknown reasons.	     */	    intel->sarea->pf_current_page =	       intel->sarea->pf_current_page & 0x3;	    intel->sarea->pf_current_page |=	       ((intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %		intel_fb->pf_num_pages) << 2;	    flip.pipes = 0x2;	 } else {	    intel->sarea->pf_current_page =	       intel->sarea->pf_current_page & (0x3 << 2);	    intel->sarea->pf_current_page |=	       (intel_fb->pf_current_page + intel_fb->pf_num_pages - 1) %	       intel_fb->pf_num_pages;	    flip.pipes = 0x1;	 }	 drmCommandWrite(intel->driFd, DRM_I915_FLIP, &flip, sizeof(flip));      }      intel_fb->pf_planes = pf_planes;   }   intel_fb->pf_active = pf_active;   intel_flip_renderbuffers(intel_fb);   intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);}/** * This will be called whenever the currently bound window is moved/resized. * XXX: actually, it seems to NOT be called when the window is only moved (BP). */voidintelWindowMoved(struct intel_context *intel){   GLcontext *ctx = &intel->ctx;   __DRIdrawablePrivate *dPriv = intel->driDrawable;   struct intel_framebuffer *intel_fb = dPriv->driverPrivate;   if (!intel->ctx.DrawBuffer) {      /* when would this happen? -BP */      intelSetFrontClipRects(intel);   }   else if (intel->ctx.DrawBuffer->Name != 0) {      /* drawing to user-created FBO - do nothing */      /* Cliprects would be set from intelDrawBuffer() */   }   else {      /* drawing to a window */      switch (intel_fb->Base._ColorDrawBufferIndexes[0]) {      case BUFFER_FRONT_LEFT:         intelSetFrontClipRects(intel);         break;      case BUFFER_BACK_LEFT:         intelSetBackClipRects(intel);         break;      default:         intelSetFrontClipRects(intel);      }	   }   if (!intel->intelScreen->driScrnPriv->dri2.enabled &&       intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {      volatile struct drm_i915_sarea *sarea = intel->sarea;      drm_clip_rect_t drw_rect = { .x1 = dPriv->x, .x2 = dPriv->x + dPriv->w,				   .y1 = dPriv->y, .y2 = dPriv->y + dPriv->h };      drm_clip_rect_t planeA_rect = { .x1 = sarea->planeA_x, .y1 = sarea->planeA_y,				     .x2 = sarea->planeA_x + sarea->planeA_w,				     .y2 = sarea->planeA_y + sarea->planeA_h };      drm_clip_rect_t planeB_rect = { .x1 = sarea->planeB_x, .y1 = sarea->planeB_y,				     .x2 = sarea->planeB_x + sarea->planeB_w,				     .y2 = sarea->planeB_y + sarea->planeB_h };      GLint areaA = driIntersectArea( drw_rect, planeA_rect );      GLint areaB = driIntersectArea( drw_rect, planeB_rect );      GLuint flags = dPriv->vblFlags;      intelUpdatePageFlipping(intel, areaA, areaB);      /* Update vblank info       */      if (areaB > areaA || (areaA == areaB && areaB > 0)) {	 flags = dPriv->vblFlags | VBLANK_FLAG_SECONDARY;      } else {	 flags = dPriv->vblFlags & ~VBLANK_FLAG_SECONDARY;      }      /* Check to see if we changed pipes */      if (flags != dPriv->vblFlags && dPriv->vblFlags &&	  !(dPriv->vblFlags & VBLANK_FLAG_NO_IRQ)) {	 int64_t count;	 drmVBlank vbl;	 int i;	 /*	  * Deal with page flipping	  */	 vbl.request.type = DRM_VBLANK_ABSOLUTE;	 if ( dPriv->vblFlags & VBLANK_FLAG_SECONDARY ) {	    vbl.request.type |= DRM_VBLANK_SECONDARY;	 }	 for (i = 0; i < intel_fb->pf_num_pages; i++) {	    if (!intel_fb->color_rb[i] ||		(intel_fb->vbl_waited - intel_fb->color_rb[i]->vbl_pending) <=		(1<<23))	       continue;	    vbl.request.sequence = intel_fb->color_rb[i]->vbl_pending;	    drmWaitVBlank(intel->driFd, &vbl);	 }	 /*	  * Update msc_base from old pipe	  */	 driDrawableGetMSC32(dPriv->driScreenPriv, dPriv, &count);	 dPriv->msc_base = count;	 /*	  * Then get new vblank_base and vblSeq values	  */	 dPriv->vblFlags = flags;	 driGetCurrentVBlank(dPriv);	 dPriv->vblank_base = dPriv->vblSeq;

⌨️ 快捷键说明

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