void xf86RotateCloseScreen(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; for (c = 0; c < xf86_config->num_crtc; c++) xf86RotateDestroy(xf86_config->crtc[c]); }
void xf86RotateCloseScreen(ScreenPtr screen) { ScrnInfoPtr scrn = xf86ScreenToScrn(screen); xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn); int c; /* This has already been destroyed when the root window was destroyed */ xf86_config->rotation_damage = NULL; for (c = 0; c < xf86_config->num_crtc; c++) xf86RotateDestroy(xf86_config->crtc[c]); }
Bool xf86CrtcRotate(xf86CrtcPtr crtc) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); ScreenPtr pScreen = xf86ScrnToScreen(pScrn); PictTransform crtc_to_fb; struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc; xFixed *new_params = NULL; int new_nparams = 0; PictFilterPtr new_filter = NULL; int new_width = 0; int new_height = 0; RRTransformPtr transform = NULL; Bool damage = FALSE; if (pScreen->isGPU) return TRUE; if (crtc->transformPresent) transform = &crtc->transform; if (!RRTransformCompute(crtc->x, crtc->y, crtc->mode.HDisplay, crtc->mode.VDisplay, crtc->rotation, transform, &crtc_to_fb, &f_crtc_to_fb, &f_fb_to_crtc) && xf86CrtcFitsScreen(crtc, &f_crtc_to_fb)) { /* * If the untranslated transformation is the identity, * disable the shadow buffer */ xf86RotateDestroy(crtc); crtc->transform_in_use = FALSE; free(new_params); new_params = NULL; new_nparams = 0; new_filter = NULL; new_width = 0; new_height = 0; } else { if (crtc->driverIsPerformingTransform) { xf86RotateDestroy(crtc); } else { /* * these are the size of the shadow pixmap, which * matches the mode, not the pre-rotated copy in the * frame buffer */ int width = crtc->mode.HDisplay; int height = crtc->mode.VDisplay; void *shadowData = crtc->rotatedData; PixmapPtr shadow = crtc->rotatedPixmap; int old_width = shadow ? shadow->drawable.width : 0; int old_height = shadow ? shadow->drawable.height : 0; /* Allocate memory for rotation */ if (old_width != width || old_height != height) { if (shadow || shadowData) { crtc->funcs->shadow_destroy(crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } shadowData = crtc->funcs->shadow_allocate(crtc, width, height); if (!shadowData) goto bail1; crtc->rotatedData = shadowData; /* shadow will be damaged in xf86RotatePrepare */ } else { /* mark shadowed area as damaged so it will be repainted */ damage = TRUE; } if (!xf86_config->rotation_damage) { /* Create damage structure */ xf86_config->rotation_damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE, pScreen, pScreen); if (!xf86_config->rotation_damage) goto bail2; /* Wrap block handler */ if (!xf86_config->BlockHandler) { xf86_config->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = xf86RotateBlockHandler; } } if (0) { bail2: if (shadow || shadowData) { crtc->funcs->shadow_destroy(crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } bail1: if (old_width && old_height) crtc->rotatedPixmap = crtc->funcs->shadow_create(crtc, NULL, old_width, old_height); return FALSE; } } #ifdef RANDR_12_INTERFACE if (transform) { if (transform->nparams) { new_params = malloc(transform->nparams * sizeof(xFixed)); if (new_params) { memcpy(new_params, transform->params, transform->nparams * sizeof(xFixed)); new_nparams = transform->nparams; new_filter = transform->filter; } } else new_filter = transform->filter; if (new_filter) { new_width = new_filter->width; new_height = new_filter->height; } } #endif crtc->transform_in_use = TRUE; } crtc->crtc_to_framebuffer = crtc_to_fb; crtc->f_crtc_to_framebuffer = f_crtc_to_fb; crtc->f_framebuffer_to_crtc = f_fb_to_crtc; free(crtc->params); crtc->params = new_params; crtc->nparams = new_nparams; crtc->filter = new_filter; crtc->filter_width = new_width; crtc->filter_height = new_height; crtc->bounds.x1 = 0; crtc->bounds.x2 = crtc->mode.HDisplay; crtc->bounds.y1 = 0; crtc->bounds.y2 = crtc->mode.VDisplay; pixman_f_transform_bounds(&f_crtc_to_fb, &crtc->bounds); if (damage) xf86CrtcDamageShadow(crtc); /* All done */ return TRUE; }
_X_EXPORT Bool xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation) { ScrnInfoPtr pScrn = crtc->scrn; xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); ScreenPtr pScreen = pScrn->pScreen; PictTransform crtc_to_fb, fb_to_crtc; PictureTransformIdentity (&crtc_to_fb); PictureTransformIdentity (&fb_to_crtc); PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc); if (rotation != RR_Rotate_0) { xFixed rot_cos, rot_sin, rot_dx, rot_dy; xFixed scale_x, scale_y, scale_dx, scale_dy; int mode_w = crtc->mode.HDisplay; int mode_h = crtc->mode.VDisplay; /* rotation */ switch (rotation & 0xf) { default: case RR_Rotate_0: rot_cos = F ( 1); rot_sin = F ( 0); rot_dx = F ( 0); rot_dy = F ( 0); break; case RR_Rotate_90: rot_cos = F ( 0); rot_sin = F ( 1); rot_dx = F ( mode_h); rot_dy = F (0); break; case RR_Rotate_180: rot_cos = F (-1); rot_sin = F ( 0); rot_dx = F (mode_w); rot_dy = F ( mode_h); break; case RR_Rotate_270: rot_cos = F ( 0); rot_sin = F (-1); rot_dx = F ( 0); rot_dy = F ( mode_w); break; } PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin); PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc); PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy); PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc); /* reflection */ scale_x = F (1); scale_dx = 0; scale_y = F (1); scale_dy = 0; if (rotation & RR_Reflect_X) { scale_x = F(-1); if (rotation & (RR_Rotate_0|RR_Rotate_180)) scale_dx = F(mode_w); else scale_dx = F(mode_h); } if (rotation & RR_Reflect_Y) { scale_y = F(-1); if (rotation & (RR_Rotate_0|RR_Rotate_180)) scale_dy = F(mode_h); else scale_dy = F(mode_w); } PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y); PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc); PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy); PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc); } /* * If the untranslated transformation is the identity, * disable the shadow buffer */ if (PictureTransformIsIdentity (&crtc_to_fb)) { crtc->transform_in_use = FALSE; PictureTransformInitTranslate (&crtc->crtc_to_framebuffer, F (-crtc->x), F (-crtc->y)); PictureTransformInitTranslate (&crtc->framebuffer_to_crtc, F ( crtc->x), F ( crtc->y)); xf86RotateDestroy (crtc); } else { PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, F(crtc->x), F(crtc->y)); PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc); /* * these are the size of the shadow pixmap, which * matches the mode, not the pre-rotated copy in the * frame buffer */ int width = mode->HDisplay; int height = mode->VDisplay; void *shadowData = crtc->rotatedData; PixmapPtr shadow = crtc->rotatedPixmap; int old_width = shadow ? shadow->drawable.width : 0; int old_height = shadow ? shadow->drawable.height : 0; /* Allocate memory for rotation */ if (old_width != width || old_height != height) { if (shadow || shadowData) { crtc->funcs->shadow_destroy (crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } shadowData = crtc->funcs->shadow_allocate (crtc, width, height); if (!shadowData) goto bail1; crtc->rotatedData = shadowData; /* shadow will be damaged in xf86RotatePrepare */ } else { /* mark shadowed area as damaged so it will be repainted */ xf86CrtcDamageShadow (crtc); } if (!xf86_config->rotation_damage) { /* Create damage structure */ xf86_config->rotation_damage = DamageCreate (NULL, NULL, DamageReportNone, TRUE, pScreen, pScreen); if (!xf86_config->rotation_damage) goto bail2; /* Wrap block handler */ xf86_config->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = xf86RotateBlockHandler; } if (0) { bail2: if (shadow || shadowData) { crtc->funcs->shadow_destroy (crtc, shadow, shadowData); crtc->rotatedPixmap = NULL; crtc->rotatedData = NULL; } bail1: if (old_width && old_height) crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc, NULL, old_width, old_height); return FALSE; } crtc->transform_in_use = TRUE; crtc->crtc_to_framebuffer = crtc_to_fb; crtc->framebuffer_to_crtc = fb_to_crtc; crtc->bounds.x1 = 0; crtc->bounds.x2 = crtc->mode.HDisplay; crtc->bounds.y1 = 0; crtc->bounds.y2 = crtc->mode.VDisplay; PictureTransformBounds (&crtc->bounds, &crtc_to_fb); } /* All done */ return TRUE; }