Tom,

I know that now everybody wants everything from you related to glamo :)

if you have time for the following:

I played further with your gdrm-waitq.c

This time I wanted to move a square pixel by pixel. I could not find
out the documentation, but I concluded that the burst command starting
with GLAMO_REG_2D_SRC_X register, would be the "one" that does
blitter.

Furthermore I tried to get the right way to do XOR, to remove the old
square. So I draw a new one, remove the old one and wait a bit.....

Unfortunately all this ends with flickering. Am I doing sthg. wrong?

Well the question is... what is the best way to implement moving of an
area with acceleration.

-- 
rgrds,
mobi phil

being mobile, but including technology
http://mobiphil.com
/*
 * gdrm-waitq.c
 *
 * Test Glamo DRM Wait Queueing
 *
 * (c) 2009 Thomas White <t...@bitwiz.org.uk>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * Copyright © 2008 Intel Corporation
 *
 *
 * Based on tests/gem_mmap.c from libdrm, to which the following notice applies:
 *
 * Copyright © 2008 Intel Corporation
 *
 * 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, sublicense,
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS 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.
 *
 * Authors:
 *    Eric Anholt <e...@anholt.net>
 *
 */

#define _FILE_OFFSET_BITS 64

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <fcntl.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <xf86drmMode.h>
#include <sys/time.h>
#include <time.h>

#include "drm.h"
#include "glamo_drm.h"
#include "drmtest.h"
#include "glamo-regs.h"

#define OBJECT_SIZE (640*480*2)


struct glamo_context
{
   int drm_fd;                        /* DRM fd */

   uint16_t *cmdq_drm;                /* Command queue cache */
   uint16_t cmd_burst_base;
   int cmdq_drm_used;
   int cmdq_drm_size;
   int cmdq_obj_used;
   uint32_t *cmdq_objs;
   unsigned int *cmdq_obj_pos;
};
typedef struct glamo_context glamoContext;


struct glamo_context *gCtx;


double utils_highresms() {

   struct timeval tv;
   suseconds_t us;
   time_t sec;

   gettimeofday(&tv, NULL);
   us = tv.tv_usec;
   sec = tv.tv_sec;

   return ((double)us+1000000.0*sec)/1000.0;

}


/* Submit the prepared command sequence to the kernel */
void glamoDRMDispatch(glamoContext *gCtx)
{
   drm_glamo_cmd_burst_t burst;
   int r;

   burst.base = gCtx->cmd_burst_base;
   burst.data = gCtx->cmdq_drm;
   burst.bufsz = gCtx->cmdq_drm_used * 2;	/* -> bytes */
   burst.nobjs = gCtx->cmdq_obj_used;
   burst.objs = gCtx->cmdq_objs;
   burst.obj_pos = gCtx->cmdq_obj_pos;

   r = drmCommandWrite(gCtx->drm_fd, DRM_GLAMO_CMDBURST,
         &burst, sizeof(burst));
   if ( r != 0 ) {
      fprintf(stderr, "DRM_GLAMO_CMDBURST failed\n");
   }

   /* Reset counts to zero for the next sequence */
   gCtx->cmdq_obj_used = 0;
   gCtx->cmdq_drm_used = 0;
}


void glamoDRMAddData(glamoContext *gCtx, uint32_t val, int len)
{
   if ( gCtx->cmdq_drm_used+4 > gCtx->cmdq_drm_size ) {
      fprintf(stderr, "Burst command too large\n");
      return;
   }

   /* Record command */
   if ( len == 2 ) {
      gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0xffff;
   } else if ( len == 4 ) {
      gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0x0000ffff;
      gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = val & 0xffff0000;
   } else {
      fprintf(stderr, "Wrong command length!\n");
   }
}


void glamoDRMAddBO(glamoContext *gCtx, int bo)
{
   if ( gCtx->cmdq_drm_used+4 > gCtx->cmdq_drm_size ) {
      fprintf(stderr, "Burst command too large\n");
      return;
   }

   /* Record object position */
   gCtx->cmdq_objs[gCtx->cmdq_obj_used] = bo;
   /* -> bytes */
   gCtx->cmdq_obj_pos[gCtx->cmdq_obj_used] = gCtx->cmdq_drm_used * 2;
   gCtx->cmdq_obj_used++;

   /* Record command */
   gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = 0x0000;
   gCtx->cmdq_drm[gCtx->cmdq_drm_used++] = 0x0000;
}


void glamoDRMStartBurst(glamoContext *gCtx, uint16_t base)
{
   gCtx->cmd_burst_base = base;
}


void glamoInitCmdqCache(glamoContext *gCtx)
{
   gCtx->cmdq_objs = malloc(1024);
   gCtx->cmdq_obj_pos = malloc(1024);
   gCtx->cmdq_obj_used = 0;
   gCtx->cmdq_drm_used = 0;
   gCtx->cmdq_drm_size = 4 * 1024;
   gCtx->cmdq_drm = malloc(gCtx->cmdq_drm_size);
}

static uint16_t random_colour()
{
   uint16_t c;

   c = random() & 0xff;
   c |= (random() & 0xff) << 8;

   return c;
}

int main(int argc, char **argv)
{
   int fd;
   struct drm_glamo_gem_create create;
   struct drm_gem_close unref;
   int ret;
   int handle;
   int i;
   drmModeResPtr r;
   drmModeCrtcPtr crtc;
   int crtc_id;
   int conn_id;
   int fb_id;
   uint32_t old_buffer_id;
   int cr, cg, cb;
   int frames;
   double tlast;

   int mod1 = atoi( argv[1]);
   int mod2 = atoi( argv[2]);
   int mod3 = atoi( argv[3]);
   /*
      int x1, x2, x3, y1, y2;
      x1=atoi( argv[1]);
      x2=atoi( argv[2]);
   //x3=atoi( argv[3]);
   y1=atoi( argv[3]);
   y2=atoi( argv[4]);
   */

   fd = drm_open_any();

   printf("Creating a GEM object\n");
   memset(&create, 0, sizeof(create));
   create.size = OBJECT_SIZE;
   ret = ioctl(fd, DRM_IOCTL_GLAMO_GEM_CREATE, &create);
   assert(ret == 0);
   handle = create.handle;
   printf("My GEM handle is %i\n", handle);

   gCtx = malloc(sizeof(*gCtx));
   gCtx->drm_fd = fd;
   glamoInitCmdqCache(gCtx);

   r = drmModeGetResources(fd);
   if ( r == NULL ) {
      printf("Could not get DRM resources\n");
      return 1;
   }
   printf("There are %i CRTCs, %i connectors, %i encoders"
         " and %i framebuffers\n",
         r->count_crtcs, r->count_connectors, r->count_encoders,
         r->count_fbs);

   crtc_id = r->crtcs[0];
   conn_id = r->connectors[0];
   printf("The first CRTC ID is %i\n", crtc_id);
   printf("The first connector ID is %i\n", conn_id);

   drmModeAddFB(fd, 480, 640, 16, 16, 480*2, handle, &fb_id);
   printf("My new FB handle is %i\n", fb_id);
   if (!fb_id) {
      printf("Could not add FB\n");
      return 1;
   }

   printf("Getting CRTC info\n");
   crtc = drmModeGetCrtc(fd, crtc_id);
   old_buffer_id = crtc->buffer_id;
   printf("Old FB handle is %i\n", old_buffer_id);

   printf("crtc=%p\n", crtc);
   if ( drmModeSetCrtc(fd, crtc_id, fb_id, 0, 0, r->connectors, 1,
            &(crtc->mode)) ) {
      printf("drmModeSetCrtc returned %i\n", ret);
   }

   cr = 31;  cb = 31;  cg = 0;
   frames = 0;
   int x1 = rand()%240;
   int y1 = rand()%320;
   int x2 = rand()%240;
   int y2= rand()%320;
   do 
   {
      int y = 0; 
      struct drm_glamo_gem_wait_rendering args;
      glamoDRMStartBurst(gCtx, GLAMO_REG_2D_DST_X);
      glamoDRMAddData(gCtx, 0, 2);
      glamoDRMAddData(gCtx, y, 2);
      glamoDRMAddBO(gCtx, handle);
      glamoDRMAddData(gCtx, 960 & 0x7ff, 2);
      glamoDRMAddData(gCtx, 640, 2);
      glamoDRMAddData(gCtx, 100, 2);
      glamoDRMAddData(gCtx, 100, 2);
      glamoDRMAddData(gCtx, 0x0000, 2);
      glamoDRMAddData(gCtx, 0x0000, 2);
      glamoDRMAddData(gCtx, 1232, 2);
      glamoDRMDispatch(gCtx);

      glamoDRMStartBurst(gCtx, GLAMO_REG_2D_COMMAND1);
      /*
         glamoDRMAddData(gCtx, mod1, 2);    
         glamoDRMAddData(gCtx, mod2 , 2);
         glamoDRMAddData(gCtx, mod3, 2);  
         */
      glamoDRMAddData(gCtx, 0x0000, 2);    /* Cmd param 1 */
      glamoDRMAddData(gCtx, 0xf0 << 8, 2); /* Cmd param 2 */
      glamoDRMAddData(gCtx, 0x0000, 2);    /* Cmd param 3 */
      glamoDRMDispatch(gCtx);


      /* Wait for Glamo to catch up */
      args.handle = handle;
      args.have_handle = 1;
      
      drmCommandWriteRead(fd, DRM_GLAMO_GEM_WAIT_RENDERING,
            &args, sizeof(args));

      while(1) 
      {
         usleep(20);

         glamoDRMStartBurst(gCtx, GLAMO_REG_2D_SRC_X);
         glamoDRMAddData(gCtx, 0, 2);
         glamoDRMAddData(gCtx, y, 2);
         glamoDRMAddData(gCtx, 0, 2);
         glamoDRMAddData(gCtx, y + 1, 2);
         glamoDRMAddBO(gCtx, handle);
         glamoDRMAddData(gCtx, 960 & 0x7ff, 2);
         glamoDRMAddData(gCtx, 640, 2);
         glamoDRMAddData(gCtx, 100, 2);
         glamoDRMAddData(gCtx, 100, 2);
         glamoDRMAddData(gCtx, 0x0000, 2);
         glamoDRMAddData(gCtx, 0x0000, 2);
         glamoDRMAddData(gCtx, 1232, 2);
         glamoDRMDispatch(gCtx);

         glamoDRMStartBurst(gCtx, GLAMO_REG_2D_COMMAND1);
         glamoDRMAddData(gCtx, 0x0000, 2);    
         glamoDRMAddData(gCtx, 0xf0 << 8, 2);
         glamoDRMAddData(gCtx, 0x0000, 2);  

         glamoDRMDispatch(gCtx);

         args.handle = handle;
         args.have_handle = 1;
         
         drmCommandWriteRead(fd, DRM_GLAMO_GEM_WAIT_RENDERING,
               &args, sizeof(args));

         glamoDRMStartBurst(gCtx, GLAMO_REG_2D_DST_X);
         glamoDRMAddData(gCtx, 0, 2);
         glamoDRMAddData(gCtx, y, 2);
         glamoDRMAddBO(gCtx, handle);
         glamoDRMAddData(gCtx, 960 & 0x7ff, 2);
         glamoDRMAddData(gCtx, 640, 2);
         glamoDRMAddData(gCtx, 100, 2);
         glamoDRMAddData(gCtx, 100, 2);
         glamoDRMAddData(gCtx, 0x0000, 2);
         glamoDRMAddData(gCtx, 0x0000, 2);
         glamoDRMAddData(gCtx, 1232, 2);
         glamoDRMDispatch(gCtx);

         glamoDRMStartBurst(gCtx, GLAMO_REG_2D_COMMAND1);

         glamoDRMAddData(gCtx, 0x0000, 2);    /* Cmd param 1 */
         glamoDRMAddData(gCtx, (0xf0 +16) << 8, 2); /* Cmd param 2 */
         glamoDRMAddData(gCtx, 0x0000, 2);    /* Cmd param 3 */
         glamoDRMDispatch(gCtx);

         /* Wait for Glamo to catch up */
         args.handle = handle;
         args.have_handle = 1;

         drmCommandWriteRead(fd, DRM_GLAMO_GEM_WAIT_RENDERING,
               &args, sizeof(args));
         y++;
         if (y > 640)
            y=0;
         usleep(10);
      }

   } while ( 1 );

   printf("Removing FB\n");
   drmModeRmFB(fd, fb_id);

   printf("Restoring original FB\n");
   if ( drmModeSetCrtc(fd, crtc_id, old_buffer_id, 0, 0, r->connectors, 1,
            &(crtc->mode)) ) {
      printf("drmModeSetCrtc returned %i\n", ret);
   }

   close(fd);

   return 0;
}
_______________________________________________
devel mailing list
devel@lists.openmoko.org
https://lists.openmoko.org/mailman/listinfo/devel

Reply via email to