summaryrefslogtreecommitdiff
path: root/uxa/uxa-render.c
diff options
context:
space:
mode:
Diffstat (limited to 'uxa/uxa-render.c')
-rw-r--r--uxa/uxa-render.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/uxa/uxa-render.c b/uxa/uxa-render.c
index abd0bf5a..525f75bb 100644
--- a/uxa/uxa-render.c
+++ b/uxa/uxa-render.c
@@ -454,6 +454,93 @@ uxa_picture_from_pixman_image(ScreenPtr pScreen,
}
static PicturePtr
+uxa_create_solid(ScreenPtr screen, uint32_t color)
+{
+ PixmapPtr pixmap;
+ PicturePtr picture;
+ uint32_t repeat = RepeatNormal;
+ int error = 0;
+
+ pixmap = (*screen->CreatePixmap)(screen, 1, 1, 32,
+ UXA_CREATE_PIXMAP_FOR_MAP);
+ if (!pixmap)
+ return 0;
+
+ if (!uxa_prepare_access((DrawablePtr)pixmap, UXA_ACCESS_RW)) {
+ (*screen->DestroyPixmap)(pixmap);
+ return 0;
+ }
+ *((uint32_t *)pixmap->devPrivate.ptr) = color;
+ uxa_finish_access((DrawablePtr)pixmap);
+
+ picture = CreatePicture(0, &pixmap->drawable,
+ PictureMatchFormat(screen, 32, PICT_a8r8g8b8),
+ CPRepeat, &repeat, serverClient, &error);
+ (*screen->DestroyPixmap)(pixmap);
+
+ return picture;
+}
+
+static PicturePtr
+uxa_acquire_solid(ScreenPtr screen, SourcePict *source)
+{
+ uxa_screen_t *uxa_screen = uxa_get_screen(screen);
+ PictSolidFill *solid = &source->solidFill;
+ PicturePtr picture;
+ int i;
+
+ if ((solid->color >> 24) == 0) {
+ if (!uxa_screen->solid_clear) {
+ uxa_screen->solid_clear = uxa_create_solid(screen, 0);
+ if (!uxa_screen->solid_clear)
+ return 0;
+ }
+ picture = uxa_screen->solid_clear;
+ goto DONE;
+ } else if (solid->color == 0xff000000) {
+ if (!uxa_screen->solid_black) {
+ uxa_screen->solid_black = uxa_create_solid(screen, 0xff000000);
+ if (!uxa_screen->solid_black)
+ return 0;
+ }
+ picture = uxa_screen->solid_black;
+ goto DONE;
+ } else if (solid->color == 0xffffffff) {
+ if (!uxa_screen->solid_white) {
+ uxa_screen->solid_white = uxa_create_solid(screen, 0xffffffff);
+ if (!uxa_screen->solid_white)
+ return 0;
+ }
+ picture = uxa_screen->solid_white;
+ goto DONE;
+ }
+
+ for (i = 0; i < uxa_screen->solid_cache_size; i++) {
+ if (uxa_screen->solid_cache[i].color == solid->color) {
+ picture = uxa_screen->solid_cache[i].picture;
+ goto DONE;
+ }
+ }
+
+ picture = uxa_create_solid(screen, solid->color);
+ if (!picture)
+ return 0;
+
+ if (uxa_screen->solid_cache_size == UXA_NUM_SOLID_CACHE) {
+ i = rand() % UXA_NUM_SOLID_CACHE;
+ FreePicture(uxa_screen->solid_cache[i].picture, 0);
+ } else
+ uxa_screen->solid_cache_size++;
+
+ uxa_screen->solid_cache[i].picture = picture;
+ uxa_screen->solid_cache[i].color = solid->color;
+
+DONE:
+ picture->refcnt++;
+ return picture;
+}
+
+static PicturePtr
uxa_acquire_pattern(ScreenPtr pScreen,
PicturePtr pSrc,
pixman_format_code_t format,
@@ -461,9 +548,16 @@ uxa_acquire_pattern(ScreenPtr pScreen,
{
PicturePtr pDst;
+ if (pSrc->pSourcePict) {
+ SourcePict *source = pSrc->pSourcePict;
+ if (source->type == SourcePictTypeSolidFill)
+ return uxa_acquire_solid (pScreen, source);
+ }
+
pDst = uxa_picture_for_pixman_format(pScreen, format, width, height);
if (!pDst)
return 0;
+
if (uxa_prepare_access(pDst->pDrawable, UXA_ACCESS_RW)) {
fbComposite(PictOpSrc, pSrc, NULL, pDst,
x, y, 0, 0, 0, 0, width, height);