forked from KolibriOS/kolibrios
transparent blit
git-svn-id: svn://kolibrios.org@829 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
710a7a5b8b
commit
a4d9a318f2
@ -292,36 +292,62 @@ int CreatePixmap(userpixmap_t *io)
|
|||||||
return ERR_OK;
|
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)
|
int LockPixmap(userpixmap_t *io)
|
||||||
{
|
{
|
||||||
pixmap_t *pixmap;
|
pixmap_t *pixmap;
|
||||||
size_t size;
|
size_t size;
|
||||||
void *usermap;
|
void *usermap;
|
||||||
|
|
||||||
dbgprintf("Lock pixmap %x\n", io->pixmap);
|
dbgprintf("Lock pixmap %x\n", io->pixmap);
|
||||||
|
|
||||||
if(io->pixmap == (pixmap_t*)-1)
|
if(io->pixmap == (pixmap_t*)-1)
|
||||||
return ERR_PARAM;
|
return ERR_PARAM;
|
||||||
else
|
else
|
||||||
pixmap = io->pixmap;
|
pixmap = io->pixmap;
|
||||||
|
|
||||||
if( (pixmap->flags & 1) == PX_LOCK )
|
if( (pixmap->flags & 1) == PX_LOCK )
|
||||||
return ERR_PARAM;
|
return ERR_PARAM;
|
||||||
|
|
||||||
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
|
size = (pixmap->pitch*pixmap->width+4095) & ~ 4095;
|
||||||
if (usermap = UserAlloc(size))
|
if (usermap = UserAlloc(size))
|
||||||
{
|
{
|
||||||
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
|
CommitPages(usermap, ((u32_t)pixmap->raw+rhd.PhisBase)|7|(1<<9), size);
|
||||||
pixmap->flags |= PX_LOCK;
|
pixmap->flags |= PX_LOCK;
|
||||||
pixmap->usermap = usermap;
|
pixmap->usermap = usermap;
|
||||||
io->usermap = usermap;
|
io->usermap = usermap;
|
||||||
io->pitch = pixmap->pitch;
|
io->pitch = pixmap->pitch;
|
||||||
dbgprintf("map at %x\n", io->usermap);
|
dbgprintf("map at %x\n", io->usermap);
|
||||||
|
|
||||||
return ERR_OK;
|
return ERR_OK;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return ERR_PARAM;
|
return ERR_PARAM;
|
||||||
};
|
};
|
||||||
|
|
||||||
int UnlockPixmap(userpixmap_t *io)
|
int UnlockPixmap(userpixmap_t *io)
|
||||||
@ -400,3 +426,57 @@ int PixBlit(pixblit_t *blit)
|
|||||||
safe_sti(ifl);
|
safe_sti(ifl);
|
||||||
return ERR_OK;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -182,6 +182,17 @@ int _stdcall srv_2d(ioctl_t *io)
|
|||||||
return UnlockPixmap((userpixmap_t*)inp);
|
return UnlockPixmap((userpixmap_t*)inp);
|
||||||
break;
|
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:
|
default:
|
||||||
return ERR_PARAM;
|
return ERR_PARAM;
|
||||||
};
|
};
|
||||||
|
@ -386,3 +386,4 @@ typedef enum _PictFormatShort {
|
|||||||
PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
|
PICT_g1 = PICT_FORMAT(1,PICT_TYPE_GRAY,0,0,0,0),
|
||||||
} PictFormatShort;
|
} PictFormatShort;
|
||||||
|
|
||||||
|
void dump_mem();
|
||||||
|
@ -42,23 +42,23 @@
|
|||||||
struct mem_block {
|
struct mem_block {
|
||||||
struct mem_block *next;
|
struct mem_block *next;
|
||||||
struct mem_block *prev;
|
struct mem_block *prev;
|
||||||
int start;
|
u32_t start;
|
||||||
int size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Initialize. How to check for an uninitialized heap?
|
/* Initialize. How to check for an uninitialized heap?
|
||||||
*/
|
*/
|
||||||
static int init_heap(struct mem_block **heap, int start, int size)
|
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)
|
if (!blocks)
|
||||||
return -1; //-ENOMEM;
|
return -1; //-ENOMEM;
|
||||||
|
|
||||||
*heap = kmalloc(sizeof(**heap));
|
*heap = malloc(sizeof(**heap));
|
||||||
if (!*heap)
|
if (!*heap)
|
||||||
{
|
{
|
||||||
kfree(blocks);
|
free(blocks);
|
||||||
return -1; //-ENOMEM;
|
return -1; //-ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +68,7 @@ static int init_heap(struct mem_block **heap, int start, int size)
|
|||||||
|
|
||||||
__clear(*heap,sizeof(**heap));
|
__clear(*heap,sizeof(**heap));
|
||||||
(*heap)->next = (*heap)->prev = blocks;
|
(*heap)->next = (*heap)->prev = blocks;
|
||||||
|
(*heap)->start |= USED_BLOCK;
|
||||||
return 0;
|
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 */
|
/* Maybe cut off the end of an existing block */
|
||||||
if (size < p->size)
|
if (size < p->size)
|
||||||
{
|
{
|
||||||
struct mem_block *newblock = kmalloc(sizeof(*newblock));
|
struct mem_block *newblock = malloc(sizeof(*newblock));
|
||||||
if (!newblock)
|
if (!newblock)
|
||||||
goto out;
|
goto out;
|
||||||
newblock->start = p->start + size;
|
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->prev = newblock;
|
||||||
p->next = newblock;
|
p->next = newblock;
|
||||||
p->size = size;
|
p->size = size;
|
||||||
p->start|=1;
|
p->start|=USED_BLOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -113,6 +114,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size)
|
|||||||
|
|
||||||
list_for_each(p, heap)
|
list_for_each(p, heap)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ( !(p->start & USED_BLOCK) && size <= p->size)
|
if ( !(p->start & USED_BLOCK) && size <= p->size)
|
||||||
return split_block(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)
|
list_for_each(p, heap)
|
||||||
if ((p->start & ~USED_BLOCK) == start)
|
if ((p->start & ~USED_BLOCK) == start)
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ static void free_block(struct mem_block *p)
|
|||||||
p->size += q->size;
|
p->size += q->size;
|
||||||
p->next = q->next;
|
p->next = q->next;
|
||||||
p->next->prev = p;
|
p->next->prev = p;
|
||||||
kfree(q);
|
free(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !(p->prev->start & USED_BLOCK))
|
if ( !(p->prev->start & USED_BLOCK))
|
||||||
@ -156,7 +157,7 @@ static void free_block(struct mem_block *p)
|
|||||||
q->size += p->size;
|
q->size += p->size;
|
||||||
q->next = p->next;
|
q->next = p->next;
|
||||||
q->next->prev = q;
|
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;
|
struct mem_block *block, **heap;
|
||||||
|
|
||||||
heap = get_heap(rhdPtr, region);
|
heap = get_heap(rhdPtr, region);
|
||||||
if (!heap || !*heap)
|
if (!heap || !*heap)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Make things easier on ourselves: all allocations at least
|
/* 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)
|
if (!block)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ( !(block->start & 1))
|
if ( !(block->start & USED_BLOCK))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
free_block(block);
|
free_block(block);
|
||||||
return 0;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -110,12 +110,7 @@ static inline void UnmapPages(void *mem, size_t size)
|
|||||||
:"a" (mem), "c"(size>>12)
|
:"a" (mem), "c"(size>>12)
|
||||||
:"edx"
|
:"edx"
|
||||||
);
|
);
|
||||||
asm volatile (
|
asm volatile ("":::"eax","ecx");
|
||||||
""
|
|
||||||
:
|
|
||||||
:
|
|
||||||
:"eax","ecx"
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
@ -187,8 +182,10 @@ __clear (void * dst, unsigned len)
|
|||||||
"rep stosb \n"
|
"rep stosb \n"
|
||||||
:"=c"(tmp),"=D"(tmp)
|
:"=c"(tmp),"=D"(tmp)
|
||||||
:"c"(len),"D"(dst)
|
:"c"(len),"D"(dst)
|
||||||
:"memory","eax","cc"
|
:"eax"
|
||||||
);
|
);
|
||||||
|
asm volatile ("":::"ecx","edi");
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user