diff options
Diffstat (limited to 'exa/exa.c')
-rw-r--r-- | exa/exa.c | 124 |
1 files changed, 90 insertions, 34 deletions
@@ -224,6 +224,43 @@ exaLog2(int val) return bits - 1; } +static void +exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, + int w, int h, int bpp) +{ + pExaPixmap->accel_blocked = 0; + + if (pExaScr->info->maxPitchPixels) { + int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8; + + if (pExaPixmap->fb_pitch > max_pitch) + pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; + } + + if (pExaScr->info->maxPitchBytes && + pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes) + pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; + + if (w > pExaScr->info->maxX) + pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH; + + if (h > pExaScr->info->maxY) + pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT; +} + +static void +exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, + int w, int h, int bpp) +{ + if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) + pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8; + else + pExaPixmap->fb_pitch = w * bpp / 8; + + pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, + pExaScr->info->pixmapPitchAlign); +} + /** * exaCreatePixmap() creates a new pixmap. * @@ -268,12 +305,8 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, if (paddedWidth / 4 > 32767 || h > 32767) return NullPixmap; - if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) - pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8; - else - pExaPixmap->fb_pitch = w * bpp / 8; - pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, - pExaScr->info->pixmapPitchAlign); + exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); + if (paddedWidth < pExaPixmap->fb_pitch) paddedWidth = pExaPixmap->fb_pitch; @@ -307,12 +340,7 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, pExaPixmap->offscreen = FALSE; pExaPixmap->fb_ptr = NULL; - if (pExaScr->info->flags & EXA_OFFSCREEN_ALIGN_POT && w != 1) - pExaPixmap->fb_pitch = (1 << (exaLog2(w - 1) + 1)) * bpp / 8; - else - pExaPixmap->fb_pitch = w * bpp / 8; - pExaPixmap->fb_pitch = EXA_ALIGN(pExaPixmap->fb_pitch, - pExaScr->info->pixmapPitchAlign); + exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; if (pExaPixmap->fb_pitch > 131071) { @@ -339,25 +367,8 @@ exaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, REGION_NULL(pScreen, &pExaPixmap->validSys); REGION_NULL(pScreen, &pExaPixmap->validFB); - /* Check whether this pixmap can be used for acceleration. */ - pExaPixmap->accel_blocked = 0; - - if (pExaScr->info->maxPitchPixels) { - int max_pitch = pExaScr->info->maxPitchPixels * (bpp + 7) / 8; - - if (pExaPixmap->fb_pitch > max_pitch) - pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; - } - - if (pExaScr->info->maxPitchBytes && - pExaPixmap->fb_pitch > pExaScr->info->maxPitchBytes) - pExaPixmap->accel_blocked |= EXA_RANGE_PITCH; - - if (w > pExaScr->info->maxX) - pExaPixmap->accel_blocked |= EXA_RANGE_WIDTH; - - if (h > pExaScr->info->maxY) - pExaPixmap->accel_blocked |= EXA_RANGE_HEIGHT; + exaSetAccelBlock(pExaScr, pExaPixmap, + w, h, bpp); return pPixmap; } @@ -373,12 +384,25 @@ exaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, if (!pPixmap) return FALSE; + pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen); pExaPixmap = ExaGetPixmapPriv(pPixmap); - if (pExaPixmap) - pExaPixmap->sys_ptr = pPixData; + if (pExaPixmap) { + if (pPixData) + pExaPixmap->sys_ptr = pPixData; + + if (devKind > 0) + pExaPixmap->sys_pitch = devKind; + + if (width > 0 && height > 0 && bitsPerPixel > 0) { + exaSetFbPitch(pExaScr, pExaPixmap, + width, height, bitsPerPixel); + + exaSetAccelBlock(pExaScr, pExaPixmap, + width, height, bitsPerPixel); + } + } - pExaScr = ExaGetScreenPriv(pPixmap->drawable.pScreen); if (pExaScr->info->ModifyPixmapHeader) { ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, @@ -675,6 +699,34 @@ exaBitmapToRegion(PixmapPtr pPix) return ret; } +static Bool +exaCreateScreenResources(ScreenPtr pScreen) +{ + ExaScreenPriv(pScreen); + PixmapPtr pScreenPixmap; + Bool b; + + pScreen->CreateScreenResources = pExaScr->SavedCreateScreenResources; + b = pScreen->CreateScreenResources(pScreen); + pScreen->CreateScreenResources = exaCreateScreenResources; + + if (!b) + return FALSE; + + pScreenPixmap = pScreen->GetScreenPixmap(pScreen); + + if (pScreenPixmap) { + ExaPixmapPriv(pScreenPixmap); + + exaSetAccelBlock(pExaScr, pExaPixmap, + pScreenPixmap->drawable.width, + pScreenPixmap->drawable.height, + pScreenPixmap->drawable.bitsPerPixel); + } + + return TRUE; +} + /** * exaCloseScreen() unwraps its wrapped screen functions and tears down EXA's * screen private, before calling down to the next CloseSccreen. @@ -696,6 +748,7 @@ exaCloseScreen(int i, ScreenPtr pScreen) pScreen->CopyWindow = pExaScr->SavedCopyWindow; pScreen->ChangeWindowAttributes = pExaScr->SavedChangeWindowAttributes; pScreen->BitmapToRegion = pExaScr->SavedBitmapToRegion; + pScreen->CreateScreenResources = pExaScr->SavedCreateScreenResources; #ifdef RENDER if (ps) { ps->Composite = pExaScr->SavedComposite; @@ -853,6 +906,9 @@ exaDriverInit (ScreenPtr pScreen, pExaScr->SavedBitmapToRegion = pScreen->BitmapToRegion; pScreen->BitmapToRegion = exaBitmapToRegion; + pExaScr->SavedCreateScreenResources = pScreen->CreateScreenResources; + pScreen->CreateScreenResources = exaCreateScreenResources; + #ifdef RENDER if (ps) { pExaScr->SavedComposite = ps->Composite; |