summaryrefslogtreecommitdiff
path: root/src/mesa/drivers/dri/i965/intel_buffers.c
diff options
context:
space:
mode:
authorJesse Barnes <jesse.barnes@intel.com>2007-10-29 11:56:31 -0700
committerJesse Barnes <jesse.barnes@intel.com>2007-10-29 12:06:00 -0700
commit38fdb47d26055e19d50cd407266b56ed4317ae0a (patch)
tree944589d67c440e7f9cef7350dde877424e087d19 /src/mesa/drivers/dri/i965/intel_buffers.c
parent40133487dbdd14456a8a4f6a5716f57a36eb1ea7 (diff)
Refactor and fix core vblank support
Consolidate support for synchronizing to and retrieving vblank counters. Also fix the core vblank code to return monotonic MSC counters, which are required by some GLX extensions. Adding support for multiple pipes to a low level driver is fairly easy, the Intel 965 driver provides simple example code (see intel_buffers.c:intelWindowMoved()). The new code bumps the media stream counter extension version to 2 and adds a new getDrawableMSC callback. This callback takes a drawablePrivate pointer, which is used to calculate the MSC value seen by clients based on the actual vblank counter(s) returned from the kernel. The new drawable private fields are as follows: - vblSeq - used for tracking vblank counts for buffer swapping - vblFlags - flags (e.g. current pipe), updated by low level driver - msc_base - MSC counter from the last time the current pipe changed - vblank_base - kernel DRM vblank counter from the last time the pipe changed Using the above variables, the core vblank code (in vblank.c) can calculate a monotonic MSC value. The low level DRI drivers are responsible for updating the current pipe (by setting VBLANK_FLAG_SECONDARY for example in vblFlags) along with msc_base and vblank_base whenever the pipe associated with a given drawable changes (again, see intelWindowMoved for an example of this). Drivers should fill in the GetDrawableMSC DriverAPIRec field to point to driDrawableGetMSC32 and add code for pipe switching as outlined above to fully support the new scheme.
Diffstat (limited to 'src/mesa/drivers/dri/i965/intel_buffers.c')
-rw-r--r--src/mesa/drivers/dri/i965/intel_buffers.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/i965/intel_buffers.c b/src/mesa/drivers/dri/i965/intel_buffers.c
index 6c8b073502..96ef9d8c20 100644
--- a/src/mesa/drivers/dri/i965/intel_buffers.c
+++ b/src/mesa/drivers/dri/i965/intel_buffers.c
@@ -33,6 +33,8 @@
#include "context.h"
#include "framebuffer.h"
#include "macros.h"
+#include "utils.h"
+#include "vblank.h"
#include "swrast/swrast.h"
GLboolean intel_intersect_cliprects( drm_clip_rect_t *dst,
@@ -190,6 +192,50 @@ void intelWindowMoved( struct intel_context *intel )
}
}
+ /* Get updated plane info so we sync against the right vblank counter */
+ if (intel->intelScreen->driScrnPriv->ddx_version.minor >= 7) {
+ drmI830Sarea *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;
+
+ /* 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;
+
+ /*
+ * 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->vblFlags, &dPriv->vblSeq);
+ dPriv->vblank_base = dPriv->vblSeq;
+ }
+ } else {
+ dPriv->vblFlags &= ~VBLANK_FLAG_SECONDARY;
+ }
+
_mesa_resize_framebuffer(&intel->ctx,
(GLframebuffer*)dPriv->driverPrivate,
dPriv->w, dPriv->h);