/* * If the given request doesn't exactly match PutImage's constraints, * wrap the image in a scratch pixmap header and let CopyArea sort it out. */ static void doShmPutImage(DrawablePtr dst, GCPtr pGC, int depth, unsigned int format, int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, char *data) { PixmapPtr pPixmap; if (format == ZPixmap || depth == 1) { pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, BitsPerPixel(depth), PixmapBytePad(w, depth), data); if (!pPixmap) return; pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); FreeScratchPixmapHeader(pPixmap); } else { GCPtr putGC = GetScratchGC(depth, dst->pScreen); if (!putGC) return; pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, CREATE_PIXMAP_USAGE_SCRATCH); if (!pPixmap) { FreeScratchGC(putGC); return; } ValidateGC(&pPixmap->drawable, putGC); (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, (format == XYPixmap) ? XYPixmap : ZPixmap, data); FreeScratchGC(putGC); if (format == XYBitmap) (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, dx, dy, 1L); else (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, dx, dy); (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); } }
static void * _glamor_color_convert_a1_a8(void *src_bits, void *dst_bits, int w, int h, int stride, int revert) { PictFormatShort dst_format, src_format; pixman_image_t *dst_image; pixman_image_t *src_image; int src_stride; if (revert == REVERT_UPLOADING_A1) { src_format = PICT_a1; dst_format = PICT_a8; src_stride = PixmapBytePad(w, 1); } else { dst_format = PICT_a1; src_format = PICT_a8; src_stride = (((w * 8 + 7) / 8) + 3) & ~3; } dst_image = pixman_image_create_bits(dst_format, w, h, dst_bits, stride); if (dst_image == NULL) { return NULL; } src_image = pixman_image_create_bits(src_format, w, h, src_bits, src_stride); if (src_image == NULL) { pixman_image_unref(dst_image); return NULL; } pixman_image_composite(PictOpSrc, src_image, NULL, dst_image, 0, 0, 0, 0, 0, 0, w, h); pixman_image_unref(src_image); pixman_image_unref(dst_image); return dst_bits; }
/* With the introduction of pixmap privates, the "screen pixmap" can no * longer be created in miScreenInit, since all the modules that could * possibly ask for pixmap private space have not been initialized at * that time. pScreen->CreateScreenResources is called after all * possible private-requesting modules have been inited; we create the * screen pixmap here. */ Bool miCreateScreenResources(ScreenPtr pScreen) { miScreenInitParmsPtr pScrInitParms; void *value; pScrInitParms = (miScreenInitParmsPtr) pScreen->devPrivate; /* if width is non-zero, pScreen->devPrivate will be a pixmap * else it will just take the value pbits */ if (pScrInitParms->width) { PixmapPtr pPixmap; /* create a pixmap with no data, then redirect it to point to * the screen */ pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, pScreen->rootDepth, 0); if (!pPixmap) return FALSE; if (!(*pScreen->ModifyPixmapHeader) (pPixmap, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel(pScreen->rootDepth), PixmapBytePad(pScrInitParms->width, pScreen->rootDepth), pScrInitParms->pbits)) return FALSE; value = (void *) pPixmap; } else { value = pScrInitParms->pbits; } free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */ pScreen->devPrivate = value; /* pPixmap or pbits */ return TRUE; }
Bool winUpdateFBPointer(ScreenPtr pScreen, void *pbits) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; /* Location of shadow framebuffer has changed */ pScreenInfo->pfb = pbits; /* Update the screen pixmap */ if (!(*pScreen->ModifyPixmapHeader) (pScreen->devPrivate, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel(pScreen->rootDepth), PixmapBytePad(pScreenInfo->dwStride, pScreenInfo->dwBPP), pScreenInfo->pfb)) { FatalError("winUpdateFramebufferPointer - Failed modifying " "screen pixmap\n"); } return TRUE; }
/** * glamor_trapezoids will generate trapezoid mask accumulating in * system memory. */ void glamor_trapezoids(CARD8 op, PicturePtr src, PicturePtr dst, PictFormatPtr mask_format, INT16 x_src, INT16 y_src, int ntrap, xTrapezoid *traps) { ScreenPtr screen = dst->pDrawable->pScreen; BoxRec bounds; PicturePtr picture; INT16 x_dst, y_dst; INT16 x_rel, y_rel; int width, height, stride; PixmapPtr pixmap; pixman_image_t *image = NULL; /* If a mask format wasn't provided, we get to choose, but behavior should * be as if there was no temporary mask the traps were accumulated into. */ if (!mask_format) { if (dst->polyEdge == PolyEdgeSharp) mask_format = PictureMatchFormat(screen, 1, PICT_a1); else mask_format = PictureMatchFormat(screen, 8, PICT_a8); for (; ntrap; ntrap--, traps++) glamor_trapezoids(op, src, dst, mask_format, x_src, y_src, 1, traps); return; } miTrapezoidBounds(ntrap, traps, &bounds); if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2) return; x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16; width = bounds.x2 - bounds.x1; height = bounds.y2 - bounds.y1; stride = PixmapBytePad(width, mask_format->depth); picture = glamor_create_mask_picture(screen, dst, mask_format, width, height); if (!picture) return; image = pixman_image_create_bits(picture->format, width, height, NULL, stride); if (!image) { FreePicture(picture, 0); return; } for (; ntrap; ntrap--, traps++) pixman_rasterize_trapezoid(image, (pixman_trapezoid_t *) traps, -bounds.x1, -bounds.y1); pixmap = glamor_get_drawable_pixmap(picture->pDrawable); screen->ModifyPixmapHeader(pixmap, width, height, mask_format->depth, BitsPerPixel(mask_format->depth), PixmapBytePad(width, mask_format->depth), pixman_image_get_data(image)); x_rel = bounds.x1 + x_src - x_dst; y_rel = bounds.y1 + y_src - y_dst; CompositePicture(op, src, picture, dst, x_rel, y_rel, 0, 0, bounds.x1, bounds.y1, bounds.x2 - bounds.x1, bounds.y2 - bounds.y1); if (image) pixman_image_unref(image); FreePicture(picture, 0); }
/** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void uxa_get_image(DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ScreenPtr screen = pDrawable->pScreen; uxa_screen_t *uxa_screen = uxa_get_screen(screen); BoxRec Box; PixmapPtr pPix = uxa_get_drawable_pixmap(pDrawable); int xoff, yoff; Bool ok; uxa_get_drawable_deltas(pDrawable, pPix, &xoff, &yoff); Box.x1 = pDrawable->y + x + xoff; Box.y1 = pDrawable->y + y + yoff; Box.x2 = Box.x1 + w; Box.y2 = Box.y1 + h; if (uxa_screen->info->flags & UXA_USE_GLAMOR) { ok = 0; if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) { ok = glamor_get_image_nf(pDrawable, x, y, w, h, format, planeMask, d); uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW); } if (!ok) goto fallback; return; } if (uxa_screen->force_fallback) goto fallback; pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff); if (pPix == NULL || uxa_screen->info->get_image == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !UXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to * think about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = uxa_screen->info->get_image(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) return; fallback: UXA_FALLBACK(("from %p (%c)\n", pDrawable, uxa_drawable_location(pDrawable))); if (uxa_prepare_access(pDrawable, UXA_ACCESS_RO)) { fbGetImage(pDrawable, x, y, w, h, format, planeMask, d); uxa_finish_access(pDrawable, UXA_ACCESS_RO); } return; }
static void glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc, int x, int y, int w, int h, int left_pad, int image_format, char *bits) { ScreenPtr screen = drawable->pScreen; PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); float fg[4], bg[4]; GLuint tex; unsigned int stride = PixmapBytePad(1, w + left_pad); RegionPtr clip; BoxPtr box; int nbox; float dest_coords[8]; const float bitmap_coords[8] = { 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, }; GLfloat xscale, yscale; glamor_pixmap_private *pixmap_priv; pixmap_priv = glamor_get_pixmap_private(pixmap); pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale); glamor_set_normalize_vcoords(xscale, yscale, x, y, x + w, y + h, glamor_priv->yInverted, dest_coords); glamor_fallback("glamor_put_image_xybitmap: disabled\n"); goto fail; if (glamor_priv->put_image_xybitmap_prog == 0) { ErrorF("no program for xybitmap putimage\n"); goto fail; } glamor_set_alu(gc->alu); if (!glamor_set_planemask(pixmap, gc->planemask)) goto fail; dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog); glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg); dispatch->glUniform4fv (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg); glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg); dispatch->glUniform4fv (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg); dispatch->glGenTextures(1, &tex); dispatch->glActiveTexture(GL_TEXTURE0); dispatch->glBindTexture(GL_TEXTURE_2D, tex); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad); dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits); dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); /* Now that we've set up our bitmap texture and the shader, shove * the destination rectangle through the cliprects and run the * shader on the resulting fragments. */ dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords); dispatch->glEnableClientState(GL_VERTEX_ARRAY); dispatch->glClientActiveTexture(GL_TEXTURE0); dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords); dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY); dispatch->glEnable(GL_SCISSOR_TEST); clip = fbGetCompositeClip(gc); for (nbox = REGION_NUM_RECTS(clip), box = REGION_RECTS(clip); nbox--; box++) { int x1 = x; int y1 = y; int x2 = x + w; int y2 = y + h; if (x1 < box->x1) x1 = box->x1; if (y1 < box->y1) y1 = box->y1; if (x2 > box->x2) x2 = box->x2; if (y2 > box->y2) y2 = box->y2; if (x1 >= x2 || y1 >= y2) continue; dispatch->glScissor(box->x1, y_flip(pixmap, box->y1), box->x2 - box->x1, box->y2 - box->y1); dispatch->glDrawArrays(GL_QUADS, 0, 4); } dispatch->glDisable(GL_SCISSOR_TEST); glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); dispatch->glDeleteTextures(1, &tex); dispatch->glDisableClientState(GL_VERTEX_ARRAY); dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY); return; glamor_set_alu(GXcopy); glamor_set_planemask(pixmap, ~0); glamor_fallback(": to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); fail: if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) && glamor_prepare_access_gc(gc)) { fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap, bits); } glamor_finish_access_gc(gc); glamor_finish_access(drawable); }
Bool winAllocateFBShadowDDNL (ScreenPtr pScreen) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; HRESULT ddrval = DD_OK; DDSURFACEDESC2 ddsdShadow; char *lpSurface = NULL; DDPIXELFORMAT ddpfPrimary; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); #endif /* Set the padded screen width */ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, pScreenInfo->dwBPP); /* Allocate memory for our shadow surface */ lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); if (lpSurface == NULL) { ErrorF ("winAllocateFBShadowDDNL - Could not allocate bits\n"); return FALSE; } /* * Initialize the framebuffer memory so we don't get a * strange display at startup */ ZeroMemory (lpSurface, pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, &pScreenPriv->pddcPrimary, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not attach clipper: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); #endif /* Attach the clipper to our display window */ ddrval = IDirectDrawClipper_SetHWnd (pScreenPriv->pddcPrimary, 0, pScreenPriv->hwndScreen); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Clipper not attached " "to window: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); #endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, (LPDIRECTDRAW*) &pScreenPriv->pdd, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not start " "DirectDraw: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); #endif /* Get a DirectDraw4 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, &IID_IDirectDraw4, (LPVOID*) &pScreenPriv->pdd4); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Failed DD4 query: %08x\n", (unsigned int) ddrval); return FALSE; } /* Are we full screen? */ if (pScreenInfo->fFullScreen) { DDSURFACEDESC2 ddsdCurrent; DWORD dwRefreshRateCurrent = 0; HDC hdc = NULL; /* Set the cooperative level to full screen */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } /* * We only need to get the current refresh rate for comparison * if a refresh rate has been passed on the command line. */ if (pScreenInfo->dwRefreshRate != 0) { ZeroMemory (&ddsdCurrent, sizeof (ddsdCurrent)); ddsdCurrent.dwSize = sizeof (ddsdCurrent); /* Get information about current display settings */ ddrval = IDirectDraw4_GetDisplayMode (pScreenPriv->pdd4, &ddsdCurrent); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get current " "refresh rate: %08x. Continuing.\n", (unsigned int) ddrval); dwRefreshRateCurrent = 0; } else { /* Grab the current refresh rate */ dwRefreshRateCurrent = ddsdCurrent.u2.dwRefreshRate; } } /* Clean up the refresh rate */ if (dwRefreshRateCurrent == pScreenInfo->dwRefreshRate) { /* * Refresh rate is non-specified or equal to current. */ pScreenInfo->dwRefreshRate = 0; } /* Grab a device context for the screen */ hdc = GetDC (NULL); if (hdc == NULL) { ErrorF ("winAllocateFBShadowDDNL - GetDC () failed\n"); return FALSE; } /* Only change the video mode when different than current mode */ if (!pScreenInfo->fMultipleMonitors && (pScreenInfo->dwWidth != GetSystemMetrics (SM_CXSCREEN) || pScreenInfo->dwHeight != GetSystemMetrics (SM_CYSCREEN) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { winDebug ("winAllocateFBShadowDDNL - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, pScreenInfo->dwRefreshRate, 0); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "full screen display mode: %08x\n", (unsigned int) ddrval); ErrorF ("winAllocateFBShadowDDNL - Using default driver refresh rate\n"); ddrval = IDirectDraw4_SetDisplayMode (pScreenPriv->pdd4, pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwBPP, 0, 0); if (FAILED(ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set default refresh rate " "full screen display mode: %08x\n", (unsigned int) ddrval); return FALSE; } } } else { winDebug ("winAllocateFBShadowDDNL - Not changing video mode\n"); } /* Release our DC */ ReleaseDC (NULL, hdc); hdc = NULL; } else { /* Set the cooperative level for windowed mode */ ddrval = IDirectDraw4_SetCooperativeLevel (pScreenPriv->pdd4, pScreenPriv->hwndScreen, DDSCL_NORMAL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not set " "cooperative level: %08x\n", (unsigned int) ddrval); return FALSE; } } /* Create the primary surface */ if (!winCreatePrimarySurfaceShadowDDNL (pScreen)) { ErrorF ("winAllocateFBShadowDDNL - winCreatePrimarySurfaceShadowDDNL " "failed\n"); return FALSE; } /* Get primary surface's pixel format */ ZeroMemory (&ddpfPrimary, sizeof (ddpfPrimary)); ddpfPrimary.dwSize = sizeof (ddpfPrimary); ddrval = IDirectDrawSurface4_GetPixelFormat (pScreenPriv->pddsPrimary4, &ddpfPrimary); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not get primary " "pixformat: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " "dwRGBBitCount: %d\n", ddpfPrimary.u2.dwRBitMask, ddpfPrimary.u3.dwGBitMask, ddpfPrimary.u4.dwBBitMask, ddpfPrimary.u1.dwRGBBitCount); #endif /* Describe the shadow surface to be created */ /* * NOTE: Do not use a DDSCAPS_VIDEOMEMORY surface, * as drawing, locking, and unlocking take forever * with video memory surfaces. In addition, * video memory is a somewhat scarce resource, * so you shouldn't be allocating video memory when * you have the option of using system memory instead. */ ZeroMemory (&ddsdShadow, sizeof (ddsdShadow)); ddsdShadow.dwSize = sizeof (ddsdShadow); ddsdShadow.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT; ddsdShadow.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; ddsdShadow.dwHeight = pScreenInfo->dwHeight; ddsdShadow.dwWidth = pScreenInfo->dwWidth; ddsdShadow.u1.lPitch = pScreenInfo->dwPaddedWidth; ddsdShadow.lpSurface = lpSurface; ddsdShadow.u4.ddpfPixelFormat = ddpfPrimary; winDebug ("winAllocateFBShadowDDNL - lPitch: %d\n", (int) pScreenInfo->dwPaddedWidth); /* Create the shadow surface */ ddrval = IDirectDraw4_CreateSurface (pScreenPriv->pdd4, &ddsdShadow, &pScreenPriv->pddsShadow4, NULL); if (FAILED (ddrval)) { ErrorF ("winAllocateFBShadowDDNL - Could not create shadow " "surface: %08x\n", (unsigned int) ddrval); return FALSE; } #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", (int) ddsdShadow.u1.lPitch); #endif /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) / pScreenInfo->dwBPP; #if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); #endif /* Save the pointer to our surface memory */ pScreenInfo->pfb = lpSurface; /* Grab the masks from the surface description */ pScreenPriv->dwRedMask = ddsdShadow.u4.ddpfPixelFormat.u2.dwRBitMask; pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; #if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Returning\n"); #endif return TRUE; }
static int ProcPanoramiXShmCreatePixmap(ClientPtr client) { ScreenPtr pScreen = NULL; PixmapPtr pMap = NULL; DrawablePtr pDraw; DepthPtr pDepth; int i, j, result, rc; ShmDescPtr shmdesc; REQUEST(xShmCreatePixmapReq); unsigned int width, height, depth; unsigned long size; PanoramiXRes *newPix; REQUEST_SIZE_MATCH(xShmCreatePixmapReq); client->errorValue = stuff->pid; if (!sharedPixmaps) return BadImplementation; LEGAL_NEW_RESOURCE(stuff->pid, client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); width = stuff->width; height = stuff->height; depth = stuff->depth; if (!width || !height || !depth) { client->errorValue = 0; return BadValue; } if (width > 32767 || height > 32767) return BadAlloc; if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) if (pDepth->depth == stuff->depth) goto CreatePmap; client->errorValue = stuff->depth; return BadValue; } CreatePmap: size = PixmapBytePad(width, depth) * height; if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { if (size < width * height) return BadAlloc; } /* thankfully, offset is unsigned */ if (stuff->offset + size < size) return BadAlloc; VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); if(!(newPix = malloc(sizeof(PanoramiXRes)))) return BadAlloc; newPix->type = XRT_PIXMAP; newPix->u.pix.shared = TRUE; newPix->info[0].id = stuff->pid; for(j = 1; j < PanoramiXNumScreens; j++) newPix->info[j].id = FakeClientID(client->index); result = Success; FOR_NSCREENS(j) { ShmScrPrivateRec *screen_priv; pScreen = screenInfo.screens[j]; screen_priv = ShmGetScreenPriv(pScreen); pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, stuff->width, stuff->height, stuff->depth, shmdesc->addr + stuff->offset); if (pMap) { dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); shmdesc->refcnt++; pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pMap->drawable.id = newPix->info[j].id; if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { (*pScreen->DestroyPixmap)(pMap); result = BadAlloc; break; } } else { result = BadAlloc; break; } } if(result == BadAlloc) { while(j--) { (*pScreen->DestroyPixmap)(pMap); FreeResource(newPix->info[j].id, RT_NONE); } free(newPix); } else AddResource(stuff->pid, XRT_PIXMAP, newPix); return result; }
static int ProcShmGetImage(ClientPtr client) { DrawablePtr pDraw; long lenPer = 0, length; Mask plane = 0; xShmGetImageReply xgi; ShmDescPtr shmdesc; int n, rc; REQUEST(xShmGetImageReq); REQUEST_SIZE_MATCH(xShmGetImageReq); if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { client->errorValue = stuff->format; return BadValue; } rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess); if (rc != Success) return rc; VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); if (pDraw->type == DRAWABLE_WINDOW) { if( /* check for being viewable */ !((WindowPtr) pDraw)->realized || /* check for being on screen */ pDraw->x + stuff->x < 0 || pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || pDraw->y + stuff->y < 0 || pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || /* check for being inside of border */ stuff->x < - wBorderWidth((WindowPtr)pDraw) || stuff->x + (int)stuff->width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || stuff->y < -wBorderWidth((WindowPtr)pDraw) || stuff->y + (int)stuff->height > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height ) return BadMatch; xgi.visual = wVisual(((WindowPtr)pDraw)); } else { if (stuff->x < 0 || stuff->x+(int)stuff->width > pDraw->width || stuff->y < 0 || stuff->y+(int)stuff->height > pDraw->height ) return BadMatch; xgi.visual = None; } xgi.type = X_Reply; xgi.length = 0; xgi.sequenceNumber = client->sequence; xgi.depth = pDraw->depth; if(stuff->format == ZPixmap) { length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; } else { lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; plane = ((Mask)1) << (pDraw->depth - 1); /* only planes asked for */ length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); } VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); xgi.size = length; if (length == 0) { /* nothing to do */ } else if (stuff->format == ZPixmap) { (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, stuff->width, stuff->height, stuff->format, stuff->planeMask, shmdesc->addr + stuff->offset); } else { length = stuff->offset; for (; plane; plane >>= 1) { if (stuff->planeMask & plane) { (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, stuff->width, stuff->height, stuff->format, plane, shmdesc->addr + length); length += lenPer; } } } if (client->swapped) { swaps(&xgi.sequenceNumber, n); swapl(&xgi.length, n); swapl(&xgi.visual, n); swapl(&xgi.size, n); } WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); return Success; }
static Bool glamor_upload_sub_pixmap_to_texture(PixmapPtr pixmap, int x, int y, int w, int h, int stride, void *bits, int pbo, PictFormatShort pict_format) { ScreenPtr screen = pixmap->drawable.pScreen; glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); GLenum format, type; int no_alpha, revert, swap_rb; glamor_pixmap_private *pixmap_priv; Bool force_clip; if (glamor_get_tex_format_type_from_pixmap(pixmap, pict_format, &format, &type, &no_alpha, &revert, &swap_rb, 1)) { glamor_fallback("Unknown pixmap depth %d.\n", pixmap->drawable.depth); return FALSE; } if (glamor_pixmap_upload_prepare(pixmap, format, no_alpha, revert, swap_rb)) return FALSE; pixmap_priv = glamor_get_pixmap_private(pixmap); force_clip = glamor_priv->gl_flavor != GLAMOR_GL_DESKTOP && !glamor_check_fbo_size(glamor_priv, w, h); if (glamor_pixmap_priv_is_large(pixmap_priv) || force_clip) { RegionRec region; BoxRec box; int n_region; glamor_pixmap_clipped_regions *clipped_regions; void *sub_bits; int i, j; sub_bits = xallocarray(h, stride); if (sub_bits == NULL) return FALSE; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; RegionInitBoxes(®ion, &box, 1); if (!force_clip) clipped_regions = glamor_compute_clipped_regions(pixmap, ®ion, &n_region, 0, 0, 0); else clipped_regions = glamor_compute_clipped_regions_ext(pixmap, ®ion, &n_region, pixmap_priv->block_w, pixmap_priv->block_h, 0, 0); DEBUGF("prepare upload %dx%d to a large pixmap %p\n", w, h, pixmap); for (i = 0; i < n_region; i++) { BoxPtr boxes; int nbox; int temp_stride; void *temp_bits; assert(pbo == 0); glamor_set_pixmap_fbo_current(pixmap_priv, clipped_regions[i].block_idx); boxes = RegionRects(clipped_regions[i].region); nbox = RegionNumRects(clipped_regions[i].region); DEBUGF("split to %d boxes\n", nbox); for (j = 0; j < nbox; j++) { temp_stride = PixmapBytePad(boxes[j].x2 - boxes[j].x1, pixmap->drawable.depth); if (boxes[j].x1 == x && temp_stride == stride) { temp_bits = (char *) bits + (boxes[j].y1 - y) * stride; } else { temp_bits = sub_bits; glamor_put_bits(temp_bits, temp_stride, bits, stride, pixmap->drawable.bitsPerPixel, boxes[j].x1 - x, boxes[j].y1 - y, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1); } DEBUGF("upload x %d y %d w %d h %d temp stride %d \n", boxes[j].x1 - x, boxes[j].y1 - y, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1, temp_stride); if (_glamor_upload_bits_to_pixmap_texture (pixmap, format, type, no_alpha, revert, swap_rb, boxes[j].x1, boxes[j].y1, boxes[j].x2 - boxes[j].x1, boxes[j].y2 - boxes[j].y1, temp_stride, temp_bits, pbo) == FALSE) { RegionUninit(®ion); free(sub_bits); assert(0); return FALSE; } } RegionDestroy(clipped_regions[i].region); } free(sub_bits); free(clipped_regions); RegionUninit(®ion); return TRUE; } else return _glamor_upload_bits_to_pixmap_texture(pixmap, format, type, no_alpha, revert, swap_rb, x, y, w, h, stride, bits, pbo); }
static Bool _glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src, DDXPointPtr points, int *widths, int numPoints, int sorted, Bool fallback) { PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *dest_pixmap_priv; int i; uint8_t *drawpixels_src = (uint8_t *) src; RegionPtr clip = fbGetCompositeClip(gc); BoxRec *pbox; int x_off, y_off; Bool ret = FALSE; dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap); if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) { glamor_fallback("pixmap has no fbo.\n"); goto fail; } /* XXX Shall we set alu here? */ if (!glamor_set_planemask(dest_pixmap, gc->planemask)) goto fail; glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off); for (i = 0; i < numPoints; i++) { int n = REGION_NUM_RECTS(clip); pbox = REGION_RECTS(clip); while (n--) { int x1 = points[i].x; int x2 = x1 + widths[i]; int y1 = points[i].y; if (pbox->y1 > points[i].y || pbox->y2 < points[i].y) break; x1 = x1 > pbox->x1 ? x1 : pbox->x1; x2 = x2 < pbox->x2 ? x2 : pbox->x2; if (x1 >= x2) continue; glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off, y1 + y_off, x2 - x1, 1, PixmapBytePad(widths[i], drawable->depth), drawpixels_src, 0); } drawpixels_src += PixmapBytePad(widths[i], drawable->depth); } ret = TRUE; goto done; fail: if (!fallback && glamor_ddx_fallback_check_pixmap(drawable)) goto done; glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) { fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted); glamor_finish_access(drawable, GLAMOR_ACCESS_RW); } ret = TRUE; done: return ret; }
/* See Porting Layer Definition - p. 55 */ void winGetSpansNativeGDI (DrawablePtr pDrawable, int nMax, DDXPointPtr pPoints, int *piWidths, int iSpans, char *pDsts) { PixmapPtr pPixmap = NULL; winPrivPixmapPtr pPixmapPriv = NULL; int iSpan; DDXPointPtr pPoint = NULL; int *piWidth = NULL; char *pDst = pDsts; int iBytesToCopy; HBITMAP hbmpWindow, hbmpOrig; BYTE *pbWindow = NULL; HDC hdcMem; ScreenPtr pScreen = pDrawable->pScreen; winScreenPriv(pScreen); int iByteWidth; /* Branch on the drawable type */ switch (pDrawable->type) { case DRAWABLE_PIXMAP: ErrorF ("winGetSpans - DRAWABLE_PIXMAP %08x\n", pDrawable); pPixmap = (PixmapPtr) pDrawable; pPixmapPriv = winGetPixmapPriv (pPixmap); /* Loop through spans */ for (iSpan = 0; iSpan < iSpans; ++iSpan) { pPoint = pPoints + iSpan; piWidth = piWidths + iSpan; iBytesToCopy = PixmapBytePad (*piWidth, pDrawable->depth); memcpy (pDst, pPixmapPriv->pbBits + pPixmapPriv->dwScanlineBytes * pPoint->y, iBytesToCopy); ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", pDrawable->width, pDrawable->height, pDrawable->depth, pPoint->x, pPoint->y, *piWidth); /* Calculate offset of next bit destination */ pDst += 4 * ((*piWidth + 31) / 32); } break; case DRAWABLE_WINDOW: ErrorF ("winGetSpans - DRAWABLE_WINDOW\n"); /* * FIXME: Making huge assumption here that we are copying the * area behind where the cursor will be displayed. We already * know the size of the cursor, so this works, for now. */ /* Create a bitmap to blit the window data to */ hbmpWindow = winCreateDIBNativeGDI (*piWidths, *piWidths, pDrawable->depth, &pbWindow, NULL); /* Open a memory HDC */ hdcMem = CreateCompatibleDC (NULL); /* Select the window bitmap */ hbmpOrig = SelectObject (hdcMem, hbmpWindow); /* Transfer the window bits to the window bitmap */ BitBlt (hdcMem, 0, 0, *piWidths, *piWidths, /* FIXME: Assuming square region */ pScreenPriv->hdcScreen, pPoints->x, pPoints->y, SRCCOPY); /* Pop the window bitmap out of the HDC */ SelectObject (hdcMem, hbmpOrig); /* Delete the memory HDC */ DeleteDC (hdcMem); hdcMem = NULL; iByteWidth = PixmapBytePad (*piWidths, pDrawable->depth); /* Loop through spans */ for (iSpan = 0; iSpan < iSpans; ++iSpan) { pPoint = pPoints + iSpan; piWidth = piWidths + iSpan; iBytesToCopy = PixmapBytePad (*piWidth, pDrawable->depth); memcpy (pDst, pbWindow + iByteWidth * (pPoint->y - pPoints->y), iBytesToCopy); ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", pDrawable->width, pDrawable->height, pDrawable->depth, pPoint->x, pPoint->y, *piWidth); /* Calculate offset of next bit destination */ pDst += 4 * ((*piWidth + 31) / 32); } /* Delete the window bitmap */ DeleteObject (hbmpWindow); break; case UNDRAWABLE_WINDOW: FatalError ("winGetSpans - UNDRAWABLE_WINDOW\n"); break; case DRAWABLE_BUFFER: FatalError ("winGetSpans - DRAWABLE_BUFFER\n"); break; default: FatalError ("winGetSpans - Unknown drawable type\n"); break; } }
void xglShmPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, unsigned int format, int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, char *data) { ScreenPtr pScreen = pDrawable->pScreen; PixmapPtr pPixmapHeader = NULL; PixmapPtr pPixmap; int saveTarget; XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); if ((format == ZPixmap) || (depth == 1)) { pPixmap = pPixmapHeader = GetScratchPixmapHeader (pScreen, w, h, depth, BitsPerPixel (depth), PixmapBytePad (w, depth), (pointer) data); /* disable any possible acceleration of this pixmap */ if (pPixmap) xglSetPixmapVisual (pPixmap, 0); } else { pPixmap = (*pScreen->CreatePixmap) (pScreen, sw, sh, depth); if (pPixmap) { GCPtr pScratchGC; if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT)) { (*pScreen->DestroyPixmap) (pPixmap); return; } xglSetPixmapVisual (pPixmap, 0); pScratchGC = GetScratchGC (depth, pScreen); if (!pScratchGC) { (*pScreen->DestroyPixmap) (pPixmap); return; } ValidateGC ((DrawablePtr) pPixmap, pScratchGC); (*pGC->ops->PutImage) ((DrawablePtr) pPixmap, pScratchGC, depth, -sx, -sy, w, h, 0, (format == XYPixmap) ? XYPixmap : ZPixmap, data); FreeScratchGC (pScratchGC); sx = sy = 0; } } if (!pPixmap) return; /* CopyArea should always be done in software */ saveTarget = pPixmapPriv->target; pPixmapPriv->target = xglPixmapTargetNo; if (format == XYBitmap) (*pGC->ops->CopyPlane) ((DrawablePtr) pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy, 1L); else (*pGC->ops->CopyArea) ((DrawablePtr) pPixmap, pDrawable, pGC, sx, sy, sw, sh, dx, dy); pPixmapPriv->target = saveTarget; if (pPixmapHeader) FreeScratchPixmapHeader (pPixmapHeader); else (*pScreen->DestroyPixmap) (pPixmap); }
/** Transfer \a pBits image to back-end server associated with \a * pDrawable's screen. If primitive subdivision optimization is * enabled, then only transfer the sections of \a pBits that are * visible (i.e., not-clipped) to the back-end server. */ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pBits) { DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum]; dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC); XImage *img; if (DMX_GCOPS_OFFSCREEN(pDrawable)) return; img = XCreateImage(dmxScreen->beDisplay, dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual, depth, format, leftPad, pBits, w, h, BitmapPad(dmxScreen->beDisplay), (format == ZPixmap) ? PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad)); if (img) { Drawable draw; DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); if (dmxSubdividePrimitives && pGC->pCompositeClip) { RegionPtr pSubImages; RegionPtr pClip; BoxRec box; BoxPtr pBox; int nBox; box.x1 = x; box.y1 = y; box.x2 = x + w; box.y2 = y + h; pSubImages = RegionCreate(&box, 1); pClip = RegionCreate(NullBox, 1); RegionCopy(pClip, pGC->pCompositeClip); RegionTranslate(pClip, -pDrawable->x, -pDrawable->y); RegionIntersect(pSubImages, pSubImages, pClip); nBox = RegionNumRects(pSubImages); pBox = RegionRects(pSubImages); while (nBox--) { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, pBox->x1 - box.x1, pBox->y1 - box.y1, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); pBox++; } RegionDestroy(pClip); RegionDestroy(pSubImages); } else { XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img, 0, 0, x, y, w, h); } XFree(img); /* Use XFree instead of XDestroyImage * because pBits is passed in from the * caller. */ dmxSync(dmxScreen, FALSE); } else { /* Error -- this should not happen! */ } }
static int ProcShmCreatePixmap(ClientPtr client) { PixmapPtr pMap; DrawablePtr pDraw; DepthPtr pDepth; int i, rc; ShmDescPtr shmdesc; ShmScrPrivateRec *screen_priv; REQUEST(xShmCreatePixmapReq); unsigned int width, height, depth; unsigned long size; REQUEST_SIZE_MATCH(xShmCreatePixmapReq); client->errorValue = stuff->pid; if (!sharedPixmaps) return BadImplementation; LEGAL_NEW_RESOURCE(stuff->pid, client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, DixGetAttrAccess); if (rc != Success) return rc; VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); width = stuff->width; height = stuff->height; depth = stuff->depth; if (!width || !height || !depth) { client->errorValue = 0; return BadValue; } if (width > 32767 || height > 32767) return BadAlloc; if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) if (pDepth->depth == stuff->depth) goto CreatePmap; client->errorValue = stuff->depth; return BadValue; } CreatePmap: size = PixmapBytePad(width, depth) * height; if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { if (size < width * height) return BadAlloc; } /* thankfully, offset is unsigned */ if (stuff->offset + size < size) return BadAlloc; VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); screen_priv = ShmGetScreenPriv(pDraw->pScreen); pMap = (*screen_priv->shmFuncs->CreatePixmap)( pDraw->pScreen, stuff->width, stuff->height, stuff->depth, shmdesc->addr + stuff->offset); if (pMap) { rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, pMap, RT_NONE, NULL, DixCreateAccess); if (rc != Success) { pDraw->pScreen->DestroyPixmap(pMap); return rc; } dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc); shmdesc->refcnt++; pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; pMap->drawable.id = stuff->pid; if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) { return Success; } pDraw->pScreen->DestroyPixmap(pMap); } return BadAlloc; }
/* See Porting Layer Definition - p. 55 */ void winSetSpansNativeGDI(DrawablePtr pDrawable, GCPtr pGC, char *pSrcs, DDXPointPtr pPoints, int *piWidths, int iSpans, int fSorted) { winGCPriv(pGC); PixmapPtr pPixmap = NULL; winPrivPixmapPtr pPixmapPriv = NULL; HBITMAP hbmpOrig = NULL; BITMAPINFO *pbmi; HRGN hrgn = NULL, combined = NULL; int nbox; BoxPtr pbox; nbox = RegionNumRects(pGC->pCompositeClip); pbox = RegionRects(pGC->pCompositeClip); if (!nbox) return; pbmi = malloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD)); combined = CreateRectRgn(pbox->x1, pbox->y1, pbox->x2, pbox->y2); nbox--; pbox++; while (nbox--) { hrgn = CreateRectRgn(pbox->x1, pbox->y1, pbox->x2, pbox->y2); CombineRgn(combined, combined, hrgn, RGN_OR); DeleteObject(hrgn); hrgn = NULL; pbox++; } /* Branch on the drawable type */ switch (pDrawable->type) { case DRAWABLE_PIXMAP: SelectClipRgn(pGCPriv->hdcMem, combined); DeleteObject(combined); combined = NULL; pPixmap = (PixmapPtr) pDrawable; pPixmapPriv = winGetPixmapPriv(pPixmap); /* Select the drawable pixmap into a DC */ hbmpOrig = SelectObject(pGCPriv->hdcMem, pPixmapPriv->hBitmap); if (hbmpOrig == NULL) FatalError("winSetSpans - DRAWABLE_PIXMAP - SelectObject () " "failed on pPixmapPriv->hBitmap\n"); while (iSpans--) { ZeroMemory(pbmi, sizeof(BITMAPINFO)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = *piWidths; pbmi->bmiHeader.biHeight = 1; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = pDrawable->depth; pbmi->bmiHeader.biCompression = BI_RGB; /* Setup color table for mono DIBs */ if (pDrawable->depth == 1) { RGBQUAD *bmiColors = &(pbmi->bmiColors[0]); bmiColors[1].rgbBlue = 255; bmiColors[1].rgbGreen = 255; bmiColors[1].rgbRed = 255; } StretchDIBits(pGCPriv->hdcMem, pPoints->x, pPoints->y, *piWidths, 1, 0, 0, *piWidths, 1, pSrcs, (BITMAPINFO *) pbmi, DIB_RGB_COLORS, g_copyROP[pGC->alu]); pSrcs += PixmapBytePad(*piWidths, pDrawable->depth); pPoints++; piWidths++; } /* Reset the clip region */ SelectClipRgn(pGCPriv->hdcMem, NULL); /* Push the drawable pixmap out of the GC HDC */ SelectObject(pGCPriv->hdcMem, hbmpOrig); break; case DRAWABLE_WINDOW: SelectClipRgn(pGCPriv->hdc, combined); DeleteObject(combined); combined = NULL; while (iSpans--) { ZeroMemory(pbmi, sizeof(BITMAPINFO)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = *piWidths; pbmi->bmiHeader.biHeight = 1; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = pDrawable->depth; pbmi->bmiHeader.biCompression = BI_RGB; /* Setup color table for mono DIBs */ if (pDrawable->depth == 1) { RGBQUAD *bmiColors = &(pbmi->bmiColors[0]); bmiColors[1].rgbBlue = 255; bmiColors[1].rgbGreen = 255; bmiColors[1].rgbRed = 255; } StretchDIBits(pGCPriv->hdc, pPoints->x, pPoints->y, *piWidths, 1, 0, 0, *piWidths, 1, pSrcs, (BITMAPINFO *) pbmi, DIB_RGB_COLORS, g_copyROP[pGC->alu]); pSrcs += PixmapBytePad(*piWidths, pDrawable->depth); pPoints++; piWidths++; } /* Reset the clip region */ SelectClipRgn(pGCPriv->hdc, NULL); break; default: FatalError("\nwinSetSpansNativeGDI - Unknown drawable type\n\n"); break; } free(pbmi); }
static int ProcShmPutImage(ClientPtr client) { GCPtr pGC; DrawablePtr pDraw; long length; ShmDescPtr shmdesc; REQUEST(xShmPutImageReq); REQUEST_SIZE_MATCH(xShmPutImageReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) return BadValue; if (stuff->format == XYBitmap) { if (stuff->depth != 1) return BadMatch; length = PixmapBytePad(stuff->totalWidth, 1); } else if (stuff->format == XYPixmap) { if (pDraw->depth != stuff->depth) return BadMatch; length = PixmapBytePad(stuff->totalWidth, 1); length *= stuff->depth; } else if (stuff->format == ZPixmap) { if (pDraw->depth != stuff->depth) return BadMatch; length = PixmapBytePad(stuff->totalWidth, stuff->depth); } else { client->errorValue = stuff->format; return BadValue; } /* * There's a potential integer overflow in this check: * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, * client); * the version below ought to avoid it */ if (stuff->totalHeight != 0 && length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { client->errorValue = stuff->totalWidth; return BadValue; } if (stuff->srcX > stuff->totalWidth) { client->errorValue = stuff->srcX; return BadValue; } if (stuff->srcY > stuff->totalHeight) { client->errorValue = stuff->srcY; return BadValue; } if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) { client->errorValue = stuff->srcWidth; return BadValue; } if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) { client->errorValue = stuff->srcHeight; return BadValue; } if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || ((stuff->format != ZPixmap) && (stuff->srcX < screenInfo.bitmapScanlinePad) && ((stuff->format == XYBitmap) || ((stuff->srcY == 0) && (stuff->srcHeight == stuff->totalHeight))))) && ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, stuff->totalWidth, stuff->srcHeight, stuff->srcX, stuff->format, shmdesc->addr + stuff->offset + (stuff->srcY * length)); else doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, stuff->totalWidth, stuff->totalHeight, stuff->srcX, stuff->srcY, stuff->srcWidth, stuff->srcHeight, stuff->dstX, stuff->dstY, shmdesc->addr + stuff->offset); if (stuff->sendEvent) { xShmCompletionEvent ev; ev.type = ShmCompletionCode; ev.drawable = stuff->drawable; ev.minorEvent = X_ShmPutImage; ev.majorEvent = ShmReqCode; ev.shmseg = stuff->shmseg; ev.offset = stuff->offset; WriteEventsToClient(client, 1, (xEvent *) &ev); } return Success; }
/** * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. * * This is probably the only case we actually care about. The rest fall through * to migration and fbGetImage, which hopefully will result in migration pushing * the pixmap out of framebuffer. */ void exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { ExaScreenPriv (pDrawable->pScreen); PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); int xoff, yoff; Bool ok; if (pExaScr->fallback_counter || pExaScr->swappedOut) goto fallback; exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); if (pExaScr->do_migration) { BoxRec Box; RegionRec Reg; ExaMigrationRec pixmaps[1]; Box.x1 = pDrawable->y + x + xoff; Box.y1 = pDrawable->y + y + yoff; Box.x2 = Box.x1 + w; Box.y2 = Box.y1 + h; REGION_INIT(pScreen, &Reg, &Box, 1); pixmaps[0].as_dst = FALSE; pixmaps[0].as_src = TRUE; pixmaps[0].pPix = pPix; pixmaps[0].pReg = &Reg; exaDoMigration(pixmaps, 1, FALSE); REGION_UNINIT(pScreen, &Reg); } pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) goto fallback; /* Only cover the ZPixmap, solid copy case. */ if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) goto fallback; /* Only try to handle the 8bpp and up cases, since we don't want to think * about <8bpp. */ if (pDrawable->bitsPerPixel < 8) goto fallback; ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, pDrawable->y + y + yoff, w, h, d, PixmapBytePad(w, pDrawable->depth)); if (ok) { exaWaitSync(pDrawable->pScreen); return; } fallback: ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); }
static int ProcPanoramiXShmGetImage(ClientPtr client) { PanoramiXRes *draw; DrawablePtr *drawables; DrawablePtr pDraw; xShmGetImageReply xgi; ShmDescPtr shmdesc; int i, x, y, w, h, format, rc; Mask plane = 0, planemask; long lenPer = 0, length, widthBytesLine; Bool isRoot; REQUEST(xShmGetImageReq); REQUEST_SIZE_MATCH(xShmGetImageReq); if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { client->errorValue = stuff->format; return BadValue; } rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, XRC_DRAWABLE, client, DixWriteAccess); if (rc != Success) return (rc == BadValue) ? BadDrawable : rc; if (draw->type == XRT_PIXMAP) return ProcShmGetImage(client); rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReadAccess); if (rc != Success) return rc; VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); x = stuff->x; y = stuff->y; w = stuff->width; h = stuff->height; format = stuff->format; planemask = stuff->planeMask; isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; if(isRoot) { if( /* check for being onscreen */ x < 0 || x + w > PanoramiXPixWidth || y < 0 || y + h > PanoramiXPixHeight ) return BadMatch; } else { if( /* check for being onscreen */ screenInfo.screens[0]->x + pDraw->x + x < 0 || screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth || screenInfo.screens[0]->y + pDraw->y + y < 0 || screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight || /* check for being inside of border */ x < - wBorderWidth((WindowPtr)pDraw) || x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || y < -wBorderWidth((WindowPtr)pDraw) || y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) return BadMatch; } drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr)); if(!drawables) return BadAlloc; drawables[0] = pDraw; for(i = 1; i < PanoramiXNumScreens; i++) { rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, DixReadAccess); if (rc != Success) { free(drawables); return rc; } } xgi.visual = wVisual(((WindowPtr)pDraw)); xgi.type = X_Reply; xgi.length = 0; xgi.sequenceNumber = client->sequence; xgi.depth = pDraw->depth; if(format == ZPixmap) { widthBytesLine = PixmapBytePad(w, pDraw->depth); length = widthBytesLine * h; } else { widthBytesLine = PixmapBytePad(w, 1); lenPer = widthBytesLine * h; plane = ((Mask)1) << (pDraw->depth - 1); length = lenPer * Ones(planemask & (plane | (plane - 1))); } VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); xgi.size = length; if (length == 0) {/* nothing to do */ } else if (format == ZPixmap) { XineramaGetImageData(drawables, x, y, w, h, format, planemask, shmdesc->addr + stuff->offset, widthBytesLine, isRoot); } else { length = stuff->offset; for (; plane; plane >>= 1) { if (planemask & plane) { XineramaGetImageData(drawables, x, y, w, h, format, plane, shmdesc->addr + length, widthBytesLine, isRoot); length += lenPer; } } } free(drawables); if (client->swapped) { int n; swaps(&xgi.sequenceNumber, n); swapl(&xgi.length, n); swapl(&xgi.visual, n); swapl(&xgi.size, n); } WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); return Success; }
void fbGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, unsigned int format, unsigned long planeMask, char *d) { FbBits *src; FbStride srcStride; int srcBpp; int srcXoff, srcYoff; FbStip *dst; FbStride dstStride; /* * XFree86 DDX empties the root borderClip when the VT is * switched away; this checks for that case */ if (!fbDrawableEnabled(pDrawable)) return; #ifdef FB_24_32BIT if (format == ZPixmap && pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth)) { fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d); return; } #endif fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff); x += pDrawable->x; y += pDrawable->y; dst = (FbStip *) d; if (format == ZPixmap || srcBpp == 1) { FbBits pm; pm = fbReplicatePixel (planeMask, srcBpp); dstStride = PixmapBytePad(w, pDrawable->depth); if (pm != FB_ALLONES) memset (d, 0, dstStride * h); dstStride /= sizeof (FbStip); fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride), FbBitsStrideToStipStride(srcStride), (x + srcXoff) * srcBpp, dst, dstStride, 0, w * srcBpp, h, GXcopy, pm, srcBpp); } else { dstStride = BitmapBytePad(w) / sizeof (FbStip); fbBltPlane (src + (y + srcYoff) * srcStride, srcStride, (x + srcXoff) * srcBpp, srcBpp, dst, dstStride, 0, w * srcBpp, h, fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES), fbAndStip(GXcopy,0,FB_STIP_ALLONES), fbXorStip(GXcopy,0,FB_STIP_ALLONES), planeMask); } }
void fbPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, int w, int h, int leftPad, int format, char *pImage) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); unsigned long i; FbStride srcStride; FbStip *src = (FbStip *) pImage; x += pDrawable->x; y += pDrawable->y; switch (format) { case XYBitmap: srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); fbPutXYImage (pDrawable, fbGetCompositeClip(pGC), pPriv->fg, pPriv->bg, pPriv->pm, pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad); break; case XYPixmap: srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip); for (i = 1 << (pDrawable->depth - 1); i; i >>= 1) { if (i & pGC->planemask) { fbPutXYImage (pDrawable, fbGetCompositeClip(pGC), FB_ALLONES, 0, fbReplicatePixel (i, pDrawable->bitsPerPixel), pGC->alu, TRUE, x, y, w, h, src, srcStride, leftPad); src += srcStride * h; } } break; case ZPixmap: #ifdef FB_24_32BIT if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth)) { srcStride = PixmapBytePad(w, pDrawable->depth); fb24_32PutZImage (pDrawable, fbGetCompositeClip(pGC), pGC->alu, (FbBits) pGC->planemask, x, y, w, h, (CARD8 *) pImage, srcStride); } else #endif { srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip); fbPutZImage (pDrawable, fbGetCompositeClip(pGC), pGC->alu, pPriv->pm, x, y, w, h, src, srcStride); } } }
Bool winScreenInit (int index, ScreenPtr pScreen, int argc, char **argv) { winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; winPrivScreenPtr pScreenPriv; HDC hdc; #if CYGDEBUG || YES winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n", pScreenInfo->dwWidth, pScreenInfo->dwHeight); #endif /* Allocate privates for this screen */ if (!winAllocatePrivates (pScreen)) { ErrorF ("winScreenInit - Couldn't allocate screen privates\n"); return FALSE; } /* Get a pointer to the privates structure that was allocated */ pScreenPriv = winGetScreenPriv (pScreen); /* Save a pointer to this screen in the screen info structure */ pScreenInfo->pScreen = pScreen; /* Save a pointer to the screen info in the screen privates structure */ /* This allows us to get back to the screen info from a screen pointer */ pScreenPriv->pScreenInfo = pScreenInfo; /* * Determine which engine to use. * * NOTE: This is done once per screen because each screen possibly has * a preferred engine specified on the command line. */ if (!winSetEngine (pScreen)) { ErrorF ("winScreenInit - winSetEngine () failed\n"); return FALSE; } /* Adjust the video mode for our engine type */ if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) { ErrorF ("winScreenInit - winAdjustVideoMode () failed\n"); return FALSE; } /* Check for supported display depth */ if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) { ErrorF ("winScreenInit - Unsupported display depth: %d\n" \ "Change your Windows display depth to 15, 16, 24, or 32 bits " "per pixel.\n", (int) pScreenInfo->dwBPP); ErrorF ("winScreenInit - Supported depths: %08x\n", WIN_SUPPORTED_BPPS); #if WIN_CHECK_DEPTH return FALSE; #endif } /* * Check that all monitors have the same display depth if we are using * multiple monitors */ if (pScreenInfo->fMultipleMonitors && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT)) { ErrorF ("winScreenInit - Monitors do not all have same pixel format / " "display depth.\n" "Using primary display only.\n"); pScreenInfo->fMultipleMonitors = FALSE; } /* Create display window */ if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) { ErrorF ("winScreenInit - pwinCreateBoundingWindow () " "failed\n"); return FALSE; } /* Get a device context */ hdc = GetDC (pScreenPriv->hwndScreen); /* Store the initial height, width, and depth of the display */ /* Are we using multiple monitors? */ if (pScreenInfo->fMultipleMonitors) { pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); /* * In this case, some of the defaults set in * winInitializeScreenDefaults() are not correct ... */ if (!pScreenInfo->fUserGaveHeightAndWidth) { pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth / WIN_DEFAULT_DPI) * 25.4; pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight / WIN_DEFAULT_DPI) * 25.4; } } else { pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); } /* Save the original bits per pixel */ pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL); /* Release the device context */ ReleaseDC (pScreenPriv->hwndScreen, hdc); /* Clear the visuals list */ miClearVisualTypes (); /* Set the padded screen width */ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, pScreenInfo->dwBPP); /* Call the engine dependent screen initialization procedure */ if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) { ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); return FALSE; } if (!g_fSoftwareCursor) winInitCursor(pScreen); else winErrorFVerb(2, "winScreenInit - Using software cursor\n"); /* Note the screen origin in a normalized coordinate space where (0,0) is at the top left of the native virtual desktop area */ pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN); pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN); ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n", index, pScreen->x, pScreen->y); #if CYGDEBUG || YES winDebug ("winScreenInit - returning\n"); #endif return TRUE; }
static void winShadowUpdateDD (ScreenPtr pScreen, shadowBufPtr pBuf) { winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; RegionPtr damage = shadowDamage(pBuf); HRESULT ddrval = DD_OK; RECT rcDest, rcSrc; POINT ptOrigin; DWORD dwBox = REGION_NUM_RECTS (damage); BoxPtr pBox = REGION_RECTS (damage); HRGN hrgnTemp = NULL, hrgnCombined = NULL; /* * Return immediately if the app is not active * and we are fullscreen, or if we have a bad display depth */ if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen) || pScreenPriv->fBadDepth) return; /* Get the origin of the window in the screen coords */ ptOrigin.x = pScreenInfo->dwXOffset; ptOrigin.y = pScreenInfo->dwYOffset; MapWindowPoints (pScreenPriv->hwndScreen, HWND_DESKTOP, (LPPOINT)&ptOrigin, 1); /* Unlock the shadow surface, so we can blit */ ddrval = IDirectDrawSurface2_Unlock (pScreenPriv->pddsShadow, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Unlock failed\n"); return; } /* * Handle small regions with multiple blits, * handle large regions by creating a clipping region and * doing a single blit constrained to that clipping region. */ if (pScreenInfo->dwClipUpdatesNBoxes == 0 || dwBox < pScreenInfo->dwClipUpdatesNBoxes) { /* Loop through all boxes in the damaged region */ while (dwBox--) { /* Assign damage box to source rectangle */ rcSrc.left = pBox->x1; rcSrc.top = pBox->y1; rcSrc.right = pBox->x2; rcSrc.bottom = pBox->y2; /* Calculate destination rectange */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Blit the damaged areas */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Get a pointer to the next box */ ++pBox; } } else { BoxPtr pBoxExtents = REGION_EXTENTS (pScreen, damage); /* Compute a GDI region from the damaged region */ hrgnCombined = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); dwBox--; pBox++; while (dwBox--) { hrgnTemp = CreateRectRgn (pBox->x1, pBox->y1, pBox->x2, pBox->y2); CombineRgn (hrgnCombined, hrgnCombined, hrgnTemp, RGN_OR); DeleteObject (hrgnTemp); pBox++; } /* Install the GDI region as a clipping region */ SelectClipRgn (pScreenPriv->hdcScreen, hrgnCombined); DeleteObject (hrgnCombined); hrgnCombined = NULL; /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; rcSrc.top = pBoxExtents->y1; rcSrc.right = pBoxExtents->x2; rcSrc.bottom = pBoxExtents->y2; /* Calculating a bounding box for the destination is trickier */ rcDest.left = ptOrigin.x + rcSrc.left; rcDest.top = ptOrigin.y + rcSrc.top; rcDest.right = ptOrigin.x + rcSrc.right; rcDest.bottom = ptOrigin.y + rcSrc.bottom; /* Our Blt should be clipped to the invalidated region */ ddrval = IDirectDrawSurface2_Blt (pScreenPriv->pddsPrimary, &rcDest, pScreenPriv->pddsShadow, &rcSrc, DDBLT_WAIT, NULL); /* Reset the clip region */ SelectClipRgn (pScreenPriv->hdcScreen, NULL); } /* Relock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, NULL, pScreenPriv->pddsdShadow, DDLOCK_WAIT, NULL); if (FAILED (ddrval)) { ErrorF ("winShadowUpdateDD - Lock failed\n"); return; } /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) { ErrorF ("winShadowUpdateDD - Memory location of the shadow " "surface has changed, trying to update the root window " "pixmap header to point to the new address. If you get " "this message and "PROJECT_NAME" freezes or crashes " "after this message then send a problem report and your " "%s file to " BUILDERADDR, g_pszLogFile); /* Location of shadow framebuffer has changed */ pScreenInfo->pfb = pScreenPriv->pddsdShadow->lpSurface; /* Update the screen pixmap */ if (!(*pScreen->ModifyPixmapHeader)(pScreen->devPrivate, pScreen->width, pScreen->height, pScreen->rootDepth, BitsPerPixel (pScreen->rootDepth), PixmapBytePad (pScreenInfo->dwStride, pScreenInfo->dwBPP), pScreenInfo->pfb)) { ErrorF ("winShadowUpdateDD - Bits changed, could not " "notify fb.\n"); return; } } }
/* See Porting Layer Definition - p. 55 */ void winGetSpansNativeGDI(DrawablePtr pDrawable, int nMax, DDXPointPtr pPoints, int *piWidths, int iSpans, char *pDsts) { PixmapPtr pPixmap = NULL; winPrivPixmapPtr pPixmapPriv = NULL; int iSpan; DDXPointPtr pPoint = NULL; int *piWidth = NULL; char *pDst = pDsts; HBITMAP hbmpWindow, hbmpOrig, hbmpOrig1; BYTE *pbWindow = NULL; HDC hdcMem, hdcMem1; ScreenPtr pScreen = pDrawable->pScreen; winScreenPriv(pScreen); /* Branch on the drawable type */ switch (pDrawable->type) { case DRAWABLE_PIXMAP: winDebug ("winGetSpans - DRAWABLE_PIXMAP %08x\n", pDrawable); pPixmap = (PixmapPtr) pDrawable; pPixmapPriv = winGetPixmapPriv(pPixmap); /* Open a memory HDC */ hdcMem1 = CreateCompatibleDC(NULL); hdcMem = CreateCompatibleDC(NULL); /* Select the drawable pixmap into a DC */ hbmpOrig1 = SelectObject(hdcMem1, pPixmapPriv->hBitmap); if (hbmpOrig1 == NULL) FatalError("winGetSpans - DRAWABLE_PIXMAP - SelectObject () " "failed on pPixmapPriv->hBitmap\n"); /* Loop through spans */ for (iSpan = 0; iSpan < iSpans; ++iSpan) { pPoint = pPoints + iSpan; piWidth = piWidths + iSpan; hbmpWindow = winCreateDIBNativeGDI(*piWidth, 1, pDrawable->depth, &pbWindow, NULL); hbmpOrig = SelectObject(hdcMem, hbmpWindow); /* Transfer the window bits to the window bitmap */ BitBlt(hdcMem, 0, 0, *piWidth, 1, hdcMem1, pPoint->x, pPoint->y, SRCCOPY); memcpy(pDst, (char *) pbWindow, PixmapBytePad(*piWidth, pDrawable->depth)); /* Pop the window bitmap out of the HDC and delete the bitmap */ SelectObject(hdcMem, hbmpOrig); DeleteObject(hbmpWindow); /* Calculate offset of next bit destination */ pDst += PixmapBytePad(*piWidth, pDrawable->depth); } /* Pop the pixmap's bitmap out of the HDC */ SelectObject(hdcMem1, hbmpOrig1); /* Delete the HDCs */ DeleteDC(hdcMem1); DeleteDC(hdcMem); break; case DRAWABLE_WINDOW: /* Open a memory HDC */ hdcMem = CreateCompatibleDC(NULL); /* Loop through spans */ for (iSpan = 0; iSpan < iSpans; ++iSpan) { pPoint = pPoints + iSpan; piWidth = piWidths + iSpan; hbmpWindow = winCreateDIBNativeGDI(*piWidth, 1, pDrawable->depth, &pbWindow, NULL); hbmpOrig = SelectObject(hdcMem, hbmpWindow); /* Transfer the window bits to the window bitmap */ BitBlt(hdcMem, 0, 0, *piWidth, 1, pScreenPriv->hdcScreen, pPoint->x, pPoint->y, SRCCOPY); memcpy(pDst, (char *) pbWindow, PixmapBytePad(*piWidth, pDrawable->depth)); /* Pop the window bitmap out of the HDC */ SelectObject(hdcMem, hbmpOrig); DeleteObject(hbmpWindow); /* Calculate offset of next bit destination */ pDst += PixmapBytePad(*piWidth, pDrawable->depth); } /* Delete the window bitmap */ DeleteDC(hdcMem); break; default: FatalError("winGetSpans - Unknown drawable type\n"); break; } }
static Bool _glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y, int w, int h, int left_pad, int image_format, char *bits, Bool fallback) { PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable); glamor_pixmap_private *pixmap_priv = glamor_get_pixmap_private(pixmap); RegionPtr clip; int x_off, y_off; Bool ret = FALSE; PixmapPtr temp_pixmap, sub_pixmap; glamor_pixmap_private *temp_pixmap_priv; BoxRec box; int stride; glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off); clip = fbGetCompositeClip(gc); if (image_format == XYBitmap) { assert(depth == 1); goto fail; } if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) { glamor_fallback("has no fbo.\n"); goto fail; } if (image_format != ZPixmap) { glamor_fallback("non-ZPixmap\n"); goto fail; } if (!glamor_set_planemask(pixmap, gc->planemask)) { goto fail; } /* create a temporary pixmap and upload the bits to that * pixmap, then apply clip copy it to the destination pixmap.*/ stride = PixmapBytePad(w, depth); box.x1 = x + drawable->x; box.y1 = y + drawable->y; box.x2 = x + w + drawable->x; box.y2 = y + h + drawable->y; if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN) || gc->alu != GXcopy) { temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0); if (temp_pixmap == NULL) goto fail; temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap); if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) { temp_pixmap_priv->base.picture = pixmap_priv->base.picture; temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture; } glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h, stride, bits, 0); glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y); glamor_destroy_pixmap(temp_pixmap); } else { glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off, w, h, stride, bits, 0); } ret = TRUE; goto done; fail: glamor_set_planemask(pixmap, ~0); if (!fallback && glamor_ddx_fallback_check_pixmap(&pixmap->drawable)) goto done; glamor_fallback("to %p (%c)\n", drawable, glamor_get_drawable_location(drawable)); sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x, y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); if (sub_pixmap) { if (clip != NULL) pixman_region_translate (clip, -x - drawable->x, -y - drawable->y); fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h, left_pad, image_format, bits); glamor_put_sub_pixmap(sub_pixmap, pixmap, x + x_off + drawable->x, y + y_off + drawable->y, w, h, GLAMOR_ACCESS_RW); if (clip != NULL) pixman_region_translate (clip, x + drawable->x, y + drawable->y); } else fbPutImage(drawable, gc, depth, x, y, w, h, left_pad, image_format, bits); ret = TRUE; done: return ret; }
Bool GXRotate(ScrnInfoPtr pScrni, DisplayModePtr mode) { GeodeRec *pGeode = GEODEPTR(pScrni); Rotation curr = pGeode->rotation; unsigned int curdw = pScrni->displayWidth; PixmapPtr pPixmap; BOOL ret; pPixmap = pScrni->pScreen->GetScreenPixmap(pScrni->pScreen); pGeode->rotation = GXGetRotation(pScrni->pScreen); /* Leave if we have nothing to do */ if (pGeode->rotation == curr && pGeode->curMode == mode) { return TRUE; } shadowRemove(pScrni->pScreen, NULL); switch (pGeode->rotation) { case RR_Rotate_0: ErrorF("Rotate to 0 degrees\n"); pScrni->displayWidth = pGeode->displayWidth; pGeode->Pitch = pGeode->displayPitch; break; case RR_Rotate_90: ErrorF("Rotate to 90 degrees\n"); pScrni->displayWidth = pScrni->pScreen->width; break; case RR_Rotate_180: ErrorF("Rotate to 180 degrees\n"); pScrni->displayWidth = pGeode->displayWidth; break; case RR_Rotate_270: ErrorF("Rotate to 270 degrees\n"); pScrni->displayWidth = pScrni->pScreen->width; break; } if (pGeode->rotation != RR_Rotate_0) { ret = shadowAdd(pScrni->pScreen, pPixmap, GXUpdate, GXWindowLinear, pGeode->rotation, NULL); if (!ret) { ErrorF("shadowAdd failed\n"); goto error; } } if (pGeode->rotation == RR_Rotate_0) pScrni->fbOffset = pGeode->displayOffset; else pScrni->fbOffset = pGeode->shadowOffset; pScrni->pScreen->ModifyPixmapHeader(pPixmap, pScrni->pScreen->width, pScrni->pScreen->height, pScrni->pScreen->rootDepth, pScrni->bitsPerPixel, PixmapBytePad(pScrni->displayWidth, pScrni-> pScreen->rootDepth), (pointer) (pGeode->FBBase + pScrni->fbOffset)); /* Don't use XAA pixmap cache or offscreen pixmaps when rotated */ #if XF86XAA if (pGeode->AccelInfoRec) { if (pGeode->rotation == RR_Rotate_0) { pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS | PIXMAP_CACHE; pGeode->AccelInfoRec->UsingPixmapCache = TRUE; pGeode->AccelInfoRec->maxOffPixWidth = 0; pGeode->AccelInfoRec->maxOffPixHeight = 0; } else { pGeode->AccelInfoRec->Flags = LINEAR_FRAMEBUFFER; pGeode->AccelInfoRec->UsingPixmapCache = FALSE; pGeode->AccelInfoRec->maxOffPixWidth = 1; pGeode->AccelInfoRec->maxOffPixHeight = 1; } } #endif return TRUE; error: /* Restore the old rotation */ pScrni->displayWidth = curdw; if (curr & (RR_Rotate_0 | RR_Rotate_180)) { pScrni->pScreen->width = pScrni->virtualX; pScrni->pScreen->height = pScrni->virtualY; } else { pScrni->pScreen->width = pScrni->virtualY; pScrni->pScreen->height = pScrni->virtualX; } pGeode->rotation = curr; return FALSE; }