* Turns out you must not set the source width/height UV registers (for planar
mode), but you have to set the scaling UV registers in order to have correct overlay. * In other words, overlay is working now! There are still issues with it, which can probably be attributed to missing bounds checks (the screen goes black when you leave full-screen mode in VLC - but not if overlay just stops). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17365 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -251,6 +251,10 @@ struct overlay_scale {
|
|||||||
#define OVERLAY_FORMAT_YCbCr411 0x9
|
#define OVERLAY_FORMAT_YCbCr411 0x9
|
||||||
#define OVERLAY_FORMAT_YCbCr420 0xc
|
#define OVERLAY_FORMAT_YCbCr420 0xc
|
||||||
|
|
||||||
|
#define OVERLAY_MIRROR_NORMAL 0x0
|
||||||
|
#define OVERLAY_MIRROR_HORIZONTAL 0x1
|
||||||
|
#define OVERLAY_MIRROR_VERTICAL 0x2
|
||||||
|
|
||||||
// The real overlay registers are written to using an update buffer
|
// The real overlay registers are written to using an update buffer
|
||||||
|
|
||||||
struct overlay_registers {
|
struct overlay_registers {
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ update_overlay(bool updateCoefficients)
|
|||||||
write_to_ring(ringBuffer, COMMAND_NOOP);
|
write_to_ring(ringBuffer, COMMAND_NOOP);
|
||||||
write_to_ring(ringBuffer, COMMAND_OVERLAY_FLIP | COMMAND_OVERLAY_CONTINUE);
|
write_to_ring(ringBuffer, COMMAND_OVERLAY_FLIP | COMMAND_OVERLAY_CONTINUE);
|
||||||
write_to_ring(ringBuffer, (uint32)gInfo->shared_info->physical_overlay_registers
|
write_to_ring(ringBuffer, (uint32)gInfo->shared_info->physical_overlay_registers
|
||||||
/* | (updateCoefficients ? OVERLAY_UPDATE_COEFFICIENTS : 0)*/);
|
/*| (updateCoefficients ? OVERLAY_UPDATE_COEFFICIENTS : 0)*/);
|
||||||
ring_command_complete(ringBuffer);
|
ring_command_complete(ringBuffer);
|
||||||
|
|
||||||
TRACE(("update overlay: UPDATE: %lx, TEST: %lx, STATUS: %lx, EXTENDED_STATUS: %lx\n",
|
TRACE(("update overlay: UPDATE: %lx, TEST: %lx, STATUS: %lx, EXTENDED_STATUS: %lx\n",
|
||||||
@@ -371,31 +371,42 @@ intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer
|
|||||||
registers->window_width = window->width;
|
registers->window_width = window->width;
|
||||||
registers->window_height = window->height;
|
registers->window_height = window->height;
|
||||||
|
|
||||||
|
// Note: in non-planar mode, you *must* not program the source width/height
|
||||||
|
// UV registers - they must stay cleared, or the chip is doing strange stuff.
|
||||||
|
// On the other hand, you have to program the UV scaling registers, or the
|
||||||
|
// result will be wrong, too.
|
||||||
registers->source_width_rgb = view->width;
|
registers->source_width_rgb = view->width;
|
||||||
registers->source_width_uv = view->width;
|
|
||||||
registers->source_height_rgb = view->height;
|
registers->source_height_rgb = view->height;
|
||||||
registers->source_height_uv = view->height;
|
registers->source_bytes_per_row_rgb = (((overlay->buffer_offset + (view->width << 1)
|
||||||
registers->source_bytes_per_row_rgb = (((overlay->buffer_offset + buffer->width + 0x1f) >> 5)
|
+ 0x1f) >> 5) - (overlay->buffer_offset >> 5) - 1) << 2;
|
||||||
- (overlay->buffer_offset >> 5) - 1);
|
|
||||||
registers->source_bytes_per_row_uv = (((overlay->buffer_offset + buffer->width + 0x1f) >> 5)
|
|
||||||
- (overlay->buffer_offset >> 5) - 1);
|
|
||||||
|
|
||||||
uint32 horizontalScale = (view->width << 12) / window->width;
|
uint32 horizontalScale = ((view->width - 1) << 12) / window->width;
|
||||||
|
uint32 verticalScale = ((view->height - 1) << 12) / window->height;
|
||||||
|
uint32 horizontalScaleUV = horizontalScale >> 1;
|
||||||
|
uint32 verticalScaleUV = verticalScale >> 1;
|
||||||
|
horizontalScale = horizontalScaleUV << 1;
|
||||||
|
verticalScale = verticalScaleUV << 1;
|
||||||
|
|
||||||
|
// horizontal scaling
|
||||||
registers->scale_rgb.horizontal_downscale_factor = horizontalScale >> 12;
|
registers->scale_rgb.horizontal_downscale_factor = horizontalScale >> 12;
|
||||||
registers->scale_rgb.horizontal_scale_fraction = horizontalScale & 0xfff;
|
registers->scale_rgb.horizontal_scale_fraction = horizontalScale & 0xfff;
|
||||||
|
registers->scale_uv.horizontal_downscale_factor = horizontalScaleUV >> 12;
|
||||||
|
registers->scale_uv.horizontal_scale_fraction = horizontalScaleUV & 0xfff;
|
||||||
|
|
||||||
uint32 verticalScale = (view->height << 12) / window->height;
|
// vertical scaling
|
||||||
registers->scale_rgb.vertical_scale_fraction = verticalScale & 0xfff;
|
registers->scale_rgb.vertical_scale_fraction = verticalScale & 0xfff;
|
||||||
|
registers->scale_uv.vertical_scale_fraction = verticalScaleUV & 0xfff;
|
||||||
registers->vertical_scale_rgb = verticalScale >> 12;
|
registers->vertical_scale_rgb = verticalScale >> 12;
|
||||||
registers->vertical_scale_uv = verticalScale >> 12;
|
registers->vertical_scale_uv = verticalScaleUV >> 12;
|
||||||
|
|
||||||
TRACE(("scale: h = %ld.%ld, v = %ld.%ld\n", horizontalScale >> 12,
|
TRACE(("scale: h = %ld.%ld, v = %ld.%ld\n", horizontalScale >> 12,
|
||||||
horizontalScale & 0xfff, verticalScale >> 12, verticalScale & 0xfff));
|
horizontalScale & 0xfff, verticalScale >> 12, verticalScale & 0xfff));
|
||||||
|
|
||||||
if (verticalScale != gInfo->last_vertical_overlay_scale
|
if (verticalScale != gInfo->last_vertical_overlay_scale
|
||||||
|| horizontalScale != gInfo->last_horizontal_overlay_scale) {
|
|| horizontalScale != gInfo->last_horizontal_overlay_scale) {
|
||||||
// TODO: recompute phase coefficients
|
// TODO: recompute phase coefficients (take from X driver)
|
||||||
updateCoefficients = true;
|
updateCoefficients = true;
|
||||||
|
|
||||||
gInfo->last_vertical_overlay_scale = verticalScale;
|
gInfo->last_vertical_overlay_scale = verticalScale;
|
||||||
gInfo->last_horizontal_overlay_scale = horizontalScale;
|
gInfo->last_horizontal_overlay_scale = horizontalScale;
|
||||||
}
|
}
|
||||||
@@ -404,19 +415,13 @@ intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer
|
|||||||
gInfo->last_overlay_frame = *(overlay_frame *)window;
|
gInfo->last_overlay_frame = *(overlay_frame *)window;
|
||||||
}
|
}
|
||||||
|
|
||||||
//registers->color_control_output_mode = true;
|
registers->color_control_output_mode = true;
|
||||||
registers->select_pipe = 0;
|
registers->select_pipe = 0;
|
||||||
|
|
||||||
// program buffer
|
// program buffer
|
||||||
|
|
||||||
registers->buffer_rgb0 = overlay->buffer_offset;
|
registers->buffer_rgb0 = overlay->buffer_offset;
|
||||||
// registers->buffer_rgb1 = overlay->buffer_offset;
|
|
||||||
// registers->buffer_u0 = overlay->buffer_offset;
|
|
||||||
// registers->buffer_u1 = overlay->buffer_offset;
|
|
||||||
// registers->buffer_v0 = overlay->buffer_offset;
|
|
||||||
// registers->buffer_v1 = overlay->buffer_offset;
|
|
||||||
registers->stride_rgb = buffer->bytes_per_row;
|
registers->stride_rgb = buffer->bytes_per_row;
|
||||||
registers->stride_uv = buffer->bytes_per_row;
|
|
||||||
|
|
||||||
switch (buffer->space) {
|
switch (buffer->space) {
|
||||||
case B_RGB15:
|
case B_RGB15:
|
||||||
@@ -433,6 +438,8 @@ intel_configure_overlay(overlay_token overlayToken, const overlay_buffer *buffer
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registers->mirroring_mode = (window->flags & B_OVERLAY_HORIZONTAL_MIRRORING) != 0
|
||||||
|
? OVERLAY_MIRROR_HORIZONTAL : OVERLAY_MIRROR_NORMAL;
|
||||||
registers->ycbcr422_order = 0;
|
registers->ycbcr422_order = 0;
|
||||||
|
|
||||||
if (!gInfo->shared_info->overlay_active) {
|
if (!gInfo->shared_info->overlay_active) {
|
||||||
|
|||||||
Reference in New Issue
Block a user