/*
 * Add a fb object for a bo.
 */
int gralloc_drm_bo_add_fb(struct gralloc_drm_bo_t *bo)
{
	uint8_t bpp;

	if (bo->fb_id)
		return 0;

	bpp = gralloc_drm_get_bpp(bo->handle->format) * 8;

	return drmModeAddFB(bo->drm->fd,
			bo->handle->width, bo->handle->height, bpp, bpp,
			bo->handle->stride, bo->fb_handle,
			(uint32_t *) &bo->fb_id);
}
static void intel_blit(struct gralloc_drm_drv_t *drv,
		struct gralloc_drm_bo_t *dst,
		struct gralloc_drm_bo_t *src,
		uint16_t dst_x1, uint16_t dst_y1,
		uint16_t dst_x2, uint16_t dst_y2,
		uint16_t src_x1, uint16_t src_y1,
		uint16_t src_x2, uint16_t src_y2)
{
	struct intel_info *info = (struct intel_info *) drv;
	struct intel_buffer *dst_ib = (struct intel_buffer *) dst;
	struct intel_buffer *src_ib = (struct intel_buffer *) src;
	drm_intel_bo *bo_table[3];
	uint32_t cmd, br13, dst_pitch, src_pitch;

	/*
	 * XY_SRC_COPY_BLT_CMD does not support scaling,
	 * rectangle dimensions much match
	 */
	if (src_x2 - src_x1 != dst_x2 - dst_x1 ||
		src_y2 - src_y1 != dst_y2 - dst_y1) {
		ALOGE("%s, src and dst rect must match", __func__);
		return;
	}

	if (dst->handle->format != src->handle->format) {
		ALOGE("%s, src and dst format must match", __func__);
		return;
	}

	/* nothing to blit */
	if (src_x2 <= src_x1 || src_y2 <= src_y1)
		return;

	/* clamp x2, y2 to surface size */
	if (src_x2 > src->handle->width)
		src_x2 = src->handle->width;
	if (src_y2 > src->handle->height)
		src_y2 = src->handle->height;

	if (dst_x2 > dst->handle->width)
		dst_x2 = dst->handle->width;
	if (dst_y2 > dst->handle->height)
		dst_y2 = dst->handle->height;

	bo_table[0] = info->batch_ibo;
	bo_table[1] = src_ib->ibo;
	bo_table[2] = dst_ib->ibo;
	if (drm_intel_bufmgr_check_aperture_space(bo_table, 3)) {
		if (batch_flush(info))
			return;
		assert(!drm_intel_bufmgr_check_aperture_space(bo_table, 3));
	}

	cmd = XY_SRC_COPY_BLT_CMD;
	br13 = 0xcc << 16; /* ROP_S/GXcopy */
	dst_pitch = dst->handle->stride;
	src_pitch = src->handle->stride;

	/* Blit pitch must be dword-aligned.  Otherwise, the hardware appears to
	 * drop the low bits.
	 */
	if (src_pitch % 4 != 0 || dst_pitch % 4 != 0) {
		ALOGE("%s, src and dst pitch must be dword aligned", __func__);
		return;
	}

	switch (gralloc_drm_get_bpp(dst->handle->format)) {
	case 1:
		break;
	case 2:
		br13 |= (1 << 24);
		break;
	case 4:
		br13 |= (1 << 24) | (1 << 25);
		cmd |= XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB;
		break;
	default:
		ALOGE("%s, copy with unsupported format", __func__);
		return;
	}

	if (info->gen >= 40) {
		if (dst_ib->tiling != I915_TILING_NONE) {
			assert(dst_pitch % 512 == 0);
			dst_pitch >>= 2;
			cmd |= XY_SRC_COPY_BLT_DST_TILED;
		}
		if (src_ib->tiling != I915_TILING_NONE) {
			assert(src_pitch % 512 == 0);
			src_pitch >>= 2;
			cmd |= XY_SRC_COPY_BLT_SRC_TILED;
		}