drm/exynos: fix to calculate CRTC shown via screen
This patch is to exactly calculate CRTC shown via screen for all cases. Refer exynos_plane_get_size() function for this. Also source position of fb is fixed when start position of CRTC is negative number. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com>
This commit is contained in:
Родитель
58f6aad7d9
Коммит
2ab9792178
|
@ -32,6 +32,42 @@ static const uint32_t formats[] = {
|
|||
DRM_FORMAT_NV12MT,
|
||||
};
|
||||
|
||||
/*
|
||||
* This function is to get X or Y size shown via screen. This needs length and
|
||||
* start position of CRTC.
|
||||
*
|
||||
* <--- length --->
|
||||
* CRTC ----------------
|
||||
* ^ start ^ end
|
||||
*
|
||||
* There are six cases from a to b.
|
||||
*
|
||||
* <----- SCREEN ----->
|
||||
* 0 last
|
||||
* ----------|------------------|----------
|
||||
* CRTCs
|
||||
* a -------
|
||||
* b -------
|
||||
* c --------------------------
|
||||
* d --------
|
||||
* e -------
|
||||
* f -------
|
||||
*/
|
||||
static int exynos_plane_get_size(int start, unsigned length, unsigned last)
|
||||
{
|
||||
int end = start + length;
|
||||
int size = 0;
|
||||
|
||||
if (start <= 0) {
|
||||
if (end > 0)
|
||||
size = min_t(unsigned, end, last);
|
||||
} else if (start <= last) {
|
||||
size = min_t(unsigned, last - start, length);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
|
||||
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
|
||||
unsigned int crtc_w, unsigned int crtc_h,
|
||||
|
@ -64,8 +100,24 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
|
|||
(unsigned long)overlay->dma_addr[i]);
|
||||
}
|
||||
|
||||
actual_w = min((unsigned)(crtc->mode.hdisplay - crtc_x), crtc_w);
|
||||
actual_h = min((unsigned)(crtc->mode.vdisplay - crtc_y), crtc_h);
|
||||
actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
|
||||
actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
|
||||
|
||||
if (crtc_x < 0) {
|
||||
if (actual_w)
|
||||
src_x -= crtc_x;
|
||||
else
|
||||
src_x += crtc_w;
|
||||
crtc_x = 0;
|
||||
}
|
||||
|
||||
if (crtc_y < 0) {
|
||||
if (actual_h)
|
||||
src_y -= crtc_y;
|
||||
else
|
||||
src_y += crtc_h;
|
||||
crtc_y = 0;
|
||||
}
|
||||
|
||||
/* set drm framebuffer data. */
|
||||
overlay->fb_x = src_x;
|
||||
|
|
Загрузка…
Ссылка в новой задаче