1 /**************************************************************************
3 Copyright 2010 Intel Corporation
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the
8 "Software"), to deal in the Software without restriction, including
9 without limitation the rights to use, copy, modify, merge, publish,
10 distribute, sub license, and/or sell copies of the Software, and to
11 permit persons to whom the Software is furnished to do so, subject to
12 the following conditions:
14 The above copyright notice and this permission notice (including the
15 next paragraph) shall be included in all copies or substantial portions
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 intel_shadow_create_bo(intel_screen_private *intel,
39 int16_t x1, int16_t y1,
40 int16_t x2, int16_t y2,
43 int w = x2 - x1, h = y2 - y1;
44 int size = h * w * intel->cpp;
47 bo = drm_intel_bo_alloc(intel->bufmgr, "shadow", size, 0);
48 if (bo && drm_intel_gem_bo_map_gtt(bo) == 0) {
49 char *dst = bo->virtual;
50 char *src = intel->shadow_buffer;
51 int src_pitch = intel->shadow_stride;
52 int row_length = w * intel->cpp;
54 src += y1 * src_pitch + x1 * intel->cpp;
56 memcpy (dst, src, row_length);
60 drm_intel_gem_bo_unmap_gtt(bo);
63 *pitch = w * intel->cpp;
67 static void intel_shadow_memcpy(intel_screen_private *intel)
69 char *src_data, *dst_data;
70 unsigned int src_pitch, dst_pitch;
75 if (drm_intel_gem_bo_map_gtt(intel->front_buffer))
78 src_data = intel->shadow_buffer;
79 dst_data = intel->front_buffer->virtual;
81 src_pitch = intel->shadow_stride;
82 dst_pitch = intel->front_pitch;
84 region = DamageRegion(intel->shadow_damage);
85 box = REGION_RECTS(region);
86 n = REGION_NUM_RECTS(region);
88 char *src = src_data + box->y1*src_pitch + box->x1*intel->cpp;
89 char *dst = dst_data + box->y1*dst_pitch + box->x1*intel->cpp;
90 int len = (box->x2 - box->x1)*intel->cpp;
91 int row = box->y2 - box->y1;
93 memcpy(dst, src, len);
101 void intel_shadow_blt(intel_screen_private *intel)
103 ScrnInfoPtr scrn = intel->scrn;
104 unsigned int dst_pitch;
110 /* Can we trust the BLT? Otherwise do an uncached mmecy. */
111 if (!intel->can_blt || IS_GEN2(intel)) {
112 intel_shadow_memcpy(intel);
116 dst_pitch = intel->front_pitch;
118 blt = XY_SRC_COPY_BLT_CMD;
120 blt |= (XY_SRC_COPY_BLT_WRITE_ALPHA |
121 XY_SRC_COPY_BLT_WRITE_RGB);
123 if (INTEL_INFO(intel)->gen >= 40) {
124 if (intel->front_tiling) {
126 blt |= XY_SRC_COPY_BLT_DST_TILED;
130 br13 = ROP_S << 16 | dst_pitch;
131 switch (intel->cpp) {
133 case 4: br13 |= 1 << 25; /* RGB8888 */
134 case 2: br13 |= 1 << 24; /* RGB565 */
138 region = DamageRegion(intel->shadow_damage);
139 box = REGION_RECTS(region);
140 n = REGION_NUM_RECTS(region);
145 bo = intel_shadow_create_bo(intel,
155 OUT_BATCH(box->y1 << 16 | box->x1);
156 OUT_BATCH(box->y2 << 16 | box->x2);
157 OUT_RELOC_FENCED(intel->front_buffer,
158 I915_GEM_DOMAIN_RENDER,
159 I915_GEM_DOMAIN_RENDER,
163 OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, 0, 0);
167 drm_intel_bo_unreference(bo);
172 void intel_shadow_create(struct intel_screen_private *intel)
174 ScrnInfoPtr scrn = intel->scrn;
175 ScreenPtr screen = scrn->pScreen;
180 pixmap = screen->GetScreenPixmap(screen);
181 stride = intel->cpp*scrn->virtualX;
182 buffer = malloc(stride * scrn->virtualY);
184 screen->ModifyPixmapHeader(pixmap,
185 scrn->virtualX, scrn->virtualY,
188 free(intel->shadow_buffer);
189 intel->shadow_buffer = buffer;
191 stride = intel->shadow_stride;
193 if (!intel->shadow_damage) {
194 intel->shadow_damage =
195 DamageCreate(NULL, NULL,
196 DamageReportNone, TRUE,
198 DamageRegister(&pixmap->drawable, intel->shadow_damage);
199 DamageSetReportAfterOp(intel->shadow_damage, TRUE);
202 scrn->displayWidth = stride / intel->cpp;
203 intel->shadow_stride = stride;