transparent blit

git-svn-id: svn://kolibrios.org@829 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2008-07-23 10:25:40 +00:00
parent 710a7a5b8b
commit a4d9a318f2
5 changed files with 145 additions and 42 deletions

View File

@ -292,36 +292,62 @@ int CreatePixmap(userpixmap_t *io)
return ERR_OK;
}
int DestroyPixmap( userpixmap_t *io)
{
pixmap_t *pixmap;
dbgprintf("Destroy pixmap %x\n", io->pixmap);
if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM;
else
pixmap = io->pixmap;
if( (pixmap->flags & 1) == PX_LOCK )
UnlockPixmap(io);
UserFree(pixmap->usermap);
rhd_mem_free(&rhd,RHD_MEM_FB,pixmap->raw);
free(pixmap);
io->pixmap = NULL;
io->usermap = NULL;
io->format = 0;
io->pitch = 0;
return ERR_OK;
};
int LockPixmap(userpixmap_t *io)
{
pixmap_t *pixmap;
size_t size;
void *usermap;
pixmap_t *pixmap;
size_t size;
void *usermap;
dbgprintf("Lock pixmap %x\n", io->pixmap);
dbgprintf("Lock pixmap %x\n", io->pixmap);
if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM;
else
pixmap = io->pixmap;
if(io->pixmap == (pixmap_t*)-1)
return ERR_PARAM;
else
pixmap = io->pixmap;
if( (pixmap->flags & 1) == PX_LOCK )
return ERR_PARAM;
if( (pixmap->flags & 1) == PX_LOCK )
return ERR_PARAM;
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
if (usermap = UserAlloc(size))
{
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
pixmap->flags |= PX_LOCK;
pixmap->usermap = usermap;
io->usermap = usermap;
io->pitch = pixmap->pitch;
dbgprintf("map at %x\n", io->usermap);
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
if (usermap = UserAlloc(size))
{
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
pixmap->flags |= PX_LOCK;
pixmap->usermap = usermap;
io->usermap = usermap;
io->pitch = pixmap->pitch;
dbgprintf("map at %x\n", io->usermap);
return ERR_OK;
}
else
return ERR_PARAM;
return ERR_OK;
}
else
return ERR_PARAM;
};
int UnlockPixmap(userpixmap_t *io)
@ -400,3 +426,57 @@ int PixBlit(pixblit_t *blit)
safe_sti(ifl);
return ERR_OK;
}
int TransBlit(pixblit_t *blit)
{
u32 *ring, write;
int w, h;
u32 ifl;
int x0, y0;
pixmap_t *srcpixmap;
pixmap_t *dstpixmap;
dbgprintf("Transblit src: %x dst: %x\n",blit->srcpix, blit->dstpix);
dstpixmap = (blit->dstpix == (void*)-1) ? &scr_pixmap : blit->dstpix ;
srcpixmap = (blit->srcpix == (void*)-1) ? &scr_pixmap : blit->srcpix ;
//dbgprintf("srcpixmap: %x dstpixmap: %x\n",srcpixmap, dstpixmap);
//dbgprintf("dst.width: %d dst.height: %d\n", dstpixmap->width,dstpixmap->height);
//dbgprintf("src.width: %d src.height: %d\n", srcpixmap->width,srcpixmap->height);
//dbgprintf("srcpitch: %x dstpitch: %x\n",
// srcpixmap->pitch_offset,dstpixmap->pitch_offset);
ifl = safe_cli();
BEGIN_RING();
OUT_RING(CP_PACKET3(RADEON_CNTL_TRANBLT, 8));
OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
RADEON_GMC_DST_PITCH_OFFSET_CNTL |
RADEON_GMC_BRUSH_NONE |
RADEON_GMC_DST_32BPP |
RADEON_GMC_SRC_DATATYPE_COLOR |
RADEON_DP_SRC_SOURCE_MEMORY |
(1 << 30) | R5XX_ROP3_S);
OUT_RING(srcpixmap->pitch_offset);
OUT_RING(dstpixmap->pitch_offset);
OUT_RING((2<<24)+5);
OUT_RING(0xFF000000);
OUT_RING(0xFF000000);
OUT_RING((blit->src_x<<16)|blit->src_y);
OUT_RING((blit->dst_x<<16)|blit->dst_y);
OUT_RING((blit->w<<16)|blit->h);
COMMIT_RING();
safe_sti(ifl);
return ERR_OK;
}

View File

@ -182,6 +182,17 @@ int _stdcall srv_2d(ioctl_t *io)
return UnlockPixmap((userpixmap_t*)inp);
break;
case PIXDESTROY:
if(io->inp_size==6)
return DestroyPixmap((userpixmap_t*)inp);
break;
case TRANSBLIT:
if(io->inp_size==8)
return TransBlit((pixblit_t*)inp);
break;
default:
return ERR_PARAM;
};

View File

@ -386,3 +386,4 @@ typedef enum _PictFormatShort {
PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
} PictFormatShort;
void dump_mem();

View File

@ -42,23 +42,23 @@
struct mem_block {
struct mem_block *next;
struct mem_block *prev;
int start;
int size;
u32_t start;
size_t size;
};
/* Initialize. How to check for an uninitialized heap?
*/
static int init_heap(struct mem_block **heap, int start, int size)
{
struct mem_block *blocks = kmalloc(sizeof(*blocks));
struct mem_block *blocks = malloc(sizeof(*blocks));
if (!blocks)
return -1; //-ENOMEM;
*heap = kmalloc(sizeof(**heap));
*heap = malloc(sizeof(**heap));
if (!*heap)
{
kfree(blocks);
free(blocks);
return -1; //-ENOMEM;
}
@ -68,6 +68,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
__clear(*heap,sizeof(**heap));
(*heap)->next = (*heap)->prev = blocks;
(*heap)->start |= USED_BLOCK;
return 0;
}
@ -90,7 +91,7 @@ static struct mem_block *split_block(struct mem_block *p, int size)
/* Maybe cut off the end of an existing block */
if (size < p->size)
{
struct mem_block *newblock = kmalloc(sizeof(*newblock));
struct mem_block *newblock = malloc(sizeof(*newblock));
if (!newblock)
goto out;
newblock->start = p->start + size;
@ -100,7 +101,7 @@ static struct mem_block *split_block(struct mem_block *p, int size)
p->next->prev = newblock;
p->next = newblock;
p->size = size;
p->start|=1;
p->start|=USED_BLOCK;
}
out:
@ -113,6 +114,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size)
list_for_each(p, heap)
{
if ( !(p->start & USED_BLOCK) && size <= p->size)
return split_block(p, size);
}
@ -128,7 +130,6 @@ static struct mem_block *find_block(struct mem_block *heap, int start)
list_for_each(p, heap)
if ((p->start & ~USED_BLOCK) == start)
return p;
return NULL;
}
@ -147,7 +148,7 @@ static void free_block(struct mem_block *p)
p->size += q->size;
p->next = q->next;
p->next->prev = p;
kfree(q);
free(q);
}
if ( !(p->prev->start & USED_BLOCK))
@ -156,7 +157,7 @@ static void free_block(struct mem_block *p)
q->size += p->size;
q->next = p->next;
q->next->prev = q;
kfree(p);
free(p);
}
}
@ -172,7 +173,7 @@ void *rhd_mem_alloc(RHDPtr rhdPtr,int region, int size)
struct mem_block *block, **heap;
heap = get_heap(rhdPtr, region);
if (!heap || !*heap)
if (!heap || !*heap)
return NULL;
/* Make things easier on ourselves: all allocations at least
@ -201,11 +202,24 @@ int rhd_mem_free(RHDPtr rhdPtr, int region, void *offset)
if (!block)
return -1;
if ( !(block->start & 1))
if ( !(block->start & USED_BLOCK))
return -1;
free_block(block);
return 0;
}
void dump_mem()
{
struct mem_block *p;
struct mem_block **heap;
heap = &rhd.fb_heap;
list_for_each(p, *heap)
{
dbgprintf("block: %x next: %x prev: %x start: %x size:%x\n",
p,p->next,p->prev,p->start,p->size);
}
}

View File

@ -110,12 +110,7 @@ static inline void UnmapPages(void *mem, size_t size)
:"a" (mem), "c"(size>>12)
:"edx"
);
asm volatile (
""
:
:
:"eax","ecx"
);
asm volatile ("":::"eax","ecx");
}
///////////////////////////////////////////////////////////////////////////////
@ -187,8 +182,10 @@ __clear (void * dst, unsigned len)
"rep stosb \n"
:"=c"(tmp),"=D"(tmp)
:"c"(len),"D"(dst)
:"memory","eax","cc"
:"eax"
);
asm volatile ("":::"ecx","edi");
};