Panning now works without modeset
authorJakob Bornecrantz <jakob@aurora.(none)>
Fri, 11 Jan 2008 16:13:48 +0000 (17:13 +0100)
committerJakob Bornecrantz <jakob@aurora.(none)>
Fri, 11 Jan 2008 16:13:48 +0000 (17:13 +0100)
linux-core/drm_crtc.c
linux-core/drm_crtc.h
linux-core/intel_display.c
tests/modedemo/demo.c

index fdf4c70..1e69eca 100644 (file)
@@ -1048,6 +1048,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
        struct drm_crtc **save_crtcs, *new_crtc;
        bool save_enabled = crtc->enabled;
        bool changed = false;
+       bool flip_or_move = false;
        struct drm_output *output;
        int count = 0, ro;
 
@@ -1055,11 +1056,13 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
        if (!save_crtcs)
                return -ENOMEM;
 
+       /* We should be able to check here if the fb has the same properties
+        * and then just flip_or_move it */
        if (crtc->fb != fb)
                changed = true;
 
        if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)
-               changed = true;
+               flip_or_move = true;
 
        if (new_mode && !drm_mode_equal(new_mode, &crtc->mode))
                changed = true;
@@ -1082,6 +1085,10 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
                }
        }
 
+       /* mode_set_base is not a required function */
+       if (flip_or_move && !crtc->funcs->mode_set_base)
+               changed = true;
+
        if (changed) {
                crtc->fb = fb;
                crtc->enabled = (new_mode != NULL);
@@ -1102,7 +1109,10 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,
                        crtc->desired_mode = new_mode;
                }
                drm_disable_unused_functions(dev);
+       } else if (flip_or_move) {
+               crtc->funcs->mode_set_base(crtc, crtc_info->x, crtc_info->y);
        }
+
        kfree(save_crtcs);
        return 0;
 }
@@ -1564,6 +1574,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
 
        if (crtc_req->count_outputs > 0) {
                u32 out_id;
+               /* Maybe we should check that count_outputs is a sensible value. */
                output_set = kmalloc(crtc_req->count_outputs *
                                     sizeof(struct drm_output *), GFP_KERNEL);
                if (!output_set) {
@@ -1589,6 +1600,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
                }
        }
 
+       /* What happens to output_set, leak? */
        ret = drm_crtc_set_config(crtc, crtc_req, mode, output_set, fb);
 
 out:
index 54e0c00..65c3704 100644 (file)
@@ -325,6 +325,10 @@ struct drm_crtc_funcs {
        /* Actually set the mode */
        void (*mode_set)(struct drm_crtc *crtc, struct drm_display_mode *mode,
                         struct drm_display_mode *adjusted_mode, int x, int y);
+
+       /* Move the crtc on the current fb to the given position *optional* */
+       void (*mode_set_base)(struct drm_crtc *crtc, int x, int y);
+
        /* Set gamma on the CRTC */
        void (*gamma_set)(struct drm_crtc *crtc, u16 r, u16 g, u16 b,
                          int regno);
index a81cfe6..e75d3c0 100644 (file)
@@ -1083,6 +1083,7 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
        .unlock = intel_crtc_unlock,
        .mode_fixup = intel_crtc_mode_fixup,
        .mode_set = intel_crtc_mode_set,
+       .mode_set_base = intel_pipe_set_base,
        .gamma_set = intel_crtc_gamma_set,
        .prepare = intel_crtc_prepare,
        .commit = intel_crtc_commit,
index 44ebacd..594d60d 100644 (file)
@@ -9,9 +9,10 @@
 #include "xf86drm.h"
 #include "xf86drmMode.h"
 
-/* setting this to 2024 gets the pitch wrong check it */
 #define SIZE_X 2048
 #define SIZE_Y 2048
+/* Pitch needs to be power of two */
+#define PITCH 2048
 
 static struct drm_mode_modeinfo mode = {
        .name = "Test mode",
@@ -82,19 +83,19 @@ int main(int argc, char **argv)
        prettyColors(fd, framebuffer->handle);
 
        printf("0 0\n");
-       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 0, 0, &out[1]->output_id, 1, &mode);
+       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 0, 0, &out[0]->output_id, 1, &mode);
        sleep(2);
 
        printf("0 100\n");
-       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 0, 100, &out[1]->output_id, 1, &mode);
+       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 0, 100, &out[0]->output_id, 1, &mode);
        sleep(2);
 
        printf("100 0\n");
-       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 100, 0, &out[1]->output_id, 1, &mode);
+       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 100, 0, &out[0]->output_id, 1, &mode);
        sleep(2);
 
        printf("100 100\n");
-       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 100, 100, &out[1]->output_id, 1, &mode);
+       drmModeSetCrtc(fd, crtc->crtc_id, framebuffer->buffer_id, 100, 100, &out[0]->output_id, 1, &mode);
        sleep(2);
 
        /* turn the crtc off just in case */
@@ -124,7 +125,7 @@ drmModeFBPtr createFB(int fd, drmModeResPtr res)
        if (ret)
                goto err;
 
-       ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, SIZE_X*4, &bo, &fb);
+       ret = drmModeAddFB(fd, SIZE_X, SIZE_Y, 32, 32, PITCH * 4, &bo, &fb);
 
        if (ret)
                goto err_bo;
@@ -165,7 +166,7 @@ int findConnectedOutputs(int fd, drmModeResPtr res, drmModeOutputPtr *out)
 
 drmModeCrtcPtr findFreeCrtc(int fd, drmModeResPtr res)
 {
-       return drmModeGetCrtc(fd, res->crtcs[1]);
+       return drmModeGetCrtc(fd, res->crtcs[0]);
 }
 
 void draw(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsigned int v, unsigned int *ptr)
@@ -174,7 +175,7 @@ void draw(unsigned int x, unsigned int y, unsigned int w, unsigned int h, unsign
 
        for (i = x; i < x + w; i++)
                for(j = y; j < y + h; j++)
-                       ptr[(i * SIZE_X) + j] = v;
+                       ptr[(i * PITCH) + j] = v;
 
 }
 
@@ -182,7 +183,7 @@ void prettyColors(int fd, unsigned int handle)
 {
        drmBO bo;
        unsigned int *ptr;
-       int i, j;
+       int i;
 
        drmBOReference(fd, handle, &bo);
        drmBOMap(fd, &bo, DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE, 0, (void**)&ptr);
@@ -191,7 +192,7 @@ void prettyColors(int fd, unsigned int handle)
                ptr[i] = 0xFFFFFFFF;
 
        for (i = 0; i < 8; i++)
-               draw(i*40, i*40, 40, 40, 0, ptr);
+               draw(i * 40, i * 40, 40, 40, 0, ptr);
 
 
        draw(200, 100, 40, 40, 0xff00ff, ptr);