drivers/gpu/drm/qxl/qxl_image.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/qxl/qxl_image.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/qxl/qxl_image.c
Extension
.c
Size
6358 bytes
Lines
243
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (stride == linesize && chunk_stride == stride) {
			remain = linesize * height;
			page = 0;
			i_data = (void *)data;

			while (remain > 0) {
				ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, page << PAGE_SHIFT);

				if (page == 0) {
					chunk = ptr;
					k_data = chunk->data;
					size = PAGE_SIZE - offsetof(struct qxl_data_chunk, data);
				} else {
					k_data = ptr;
					size = PAGE_SIZE;
				}
				size = min(size, remain);

				memcpy(k_data, i_data, size);

				qxl_bo_kunmap_atomic_page(qdev, chunk_bo, ptr);
				i_data += size;
				remain -= size;
				page++;
			}
		} else {
			unsigned int page_base, page_offset, out_offset;

			for (i = 0 ; i < height ; ++i) {
				i_data = (void *)data + i * stride;
				remain = linesize;
				out_offset = offsetof(struct qxl_data_chunk, data) + i * chunk_stride;

				while (remain > 0) {
					page_base = out_offset & PAGE_MASK;
					page_offset = offset_in_page(out_offset);
					size = min((int)(PAGE_SIZE - page_offset), remain);

					ptr = qxl_bo_kmap_atomic_page(qdev, chunk_bo, page_base);
					k_data = ptr + page_offset;
					memcpy(k_data, i_data, size);
					qxl_bo_kunmap_atomic_page(qdev, chunk_bo, ptr);
					remain -= size;
					i_data += size;
					out_offset += size;
				}
			}
		}
	}
	qxl_bo_vunmap_locked(chunk_bo);

	image_bo = dimage->bo;
	ptr = qxl_bo_kmap_atomic_page(qdev, image_bo, 0);
	image = ptr;

	image->descriptor.id = 0;
	image->descriptor.type = SPICE_IMAGE_TYPE_BITMAP;

	image->descriptor.flags = 0;
	image->descriptor.width = width;
	image->descriptor.height = height;

	switch (depth) {
	case 1:
		/* TODO: BE? check by arch? */
		image->u.bitmap.format = SPICE_BITMAP_FMT_1BIT_BE;
		break;
	case 24:
		image->u.bitmap.format = SPICE_BITMAP_FMT_24BIT;
		break;
	case 32:
		image->u.bitmap.format = SPICE_BITMAP_FMT_32BIT;
		break;
	default:
		DRM_ERROR("unsupported image bit depth\n");
		qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);
		return -EINVAL;
	}
	image->u.bitmap.flags = QXL_BITMAP_TOP_DOWN;
	image->u.bitmap.x = width;
	image->u.bitmap.y = height;
	image->u.bitmap.stride = chunk_stride;
	image->u.bitmap.palette = 0;
	image->u.bitmap.data = qxl_bo_physical_address(qdev, chunk_bo, 0);

	qxl_bo_kunmap_atomic_page(qdev, image_bo, ptr);

	return 0;
}

Annotation

Implementation Notes