2 Copyright (c) 2002, Thomas Kurschel
5 Part of Radeon accelerant
10 #include "GlobalData.h"
11 #include "radeon_interface.h"
12 #include "video_overlay.h"
14 #include <sys/ioctl.h>
16 #include "overlay_regs.h"
19 // we could add support of planar modes and YUV modes
20 // but I neither know how planar modes are defined nor
21 // whether there is any program that makes use of them
22 static uint32 overlay_colorspaces
[] =
24 B_RGB15
, B_RGB16
, B_RGB32
, B_YCbCr422
, 0
28 // public function: number of overlay units
29 uint32
OVERLAY_COUNT( const display_mode
*dm
)
39 // public function: return list of supported overlay colour spaces
40 // dm - display mode where overlay is to be used
41 const uint32
*OVERLAY_SUPPORTED_SPACES( const display_mode
*dm
)
47 return overlay_colorspaces
;
51 // public function: returns supported features
52 // color_space - overlay's colour space
53 uint32
OVERLAY_SUPPORTED_FEATURES( uint32 color_space
)
61 B_OVERLAY_HORIZONTAL_FILTERING
|
62 B_OVERLAY_VERTICAL_FILTERING
;
66 // public function: allocates overlay buffer
67 // cs - overlay's colour space
68 // width, height - width and height of overlay buffer
69 const overlay_buffer
*ALLOCATE_OVERLAY_BUFFER( color_space cs
, uint16 width
, uint16 height
)
71 virtual_card
*vc
= ai
->vc
;
72 shared_info
*si
= ai
->si
;
74 overlay_buffer_node
*node
;
75 overlay_buffer
*buffer
;
77 uint ati_space
, test_reg
, bpp
;
83 SHOW_FLOW0( 3, "RGB15" );
85 ati_space
= RADEON_SCALER_SOURCE_15BPP
>> 8;
89 SHOW_FLOW0( 3, "RGB16" );
91 ati_space
= RADEON_SCALER_SOURCE_16BPP
>> 8;
95 SHOW_FLOW0( 3, "RGB32" );
97 ati_space
= RADEON_SCALER_SOURCE_32BPP
>> 8;
101 SHOW_FLOW0( 3, "YCbCr422" );
103 // strange naming convention: VYUY has to be read backward,
104 // i.e. you get (low to high address) YUYV, which is what we want!
105 ati_space
= RADEON_SCALER_SOURCE_VYUY422
>> 8;
108 // YUV12 is planar pixel format consisting of two or three planes
109 // I have no clue whether and how this format is used in BeOS
110 // (don't even know how it is defined officially)
112 SHOW_FLOW0( 3, "YUV12" );
115 ati_space = RADEON_SCALER_SOURCE_YUV12 >> 8;
119 SHOW_FLOW( 3, "Unsupported format (%x)", (int)cs
);
123 node
= malloc( sizeof( overlay_buffer_node
));
127 node
->ati_space
= ati_space
;
128 node
->test_reg
= test_reg
;
130 ACQUIRE_BEN( si
->engine
.lock
);
132 // alloc graphics mem
133 buffer
= &node
->buffer
;
136 buffer
->width
= width
;
137 buffer
->height
= height
;
138 buffer
->bytes_per_row
= (width
* bpp
+ 0xf) & ~0xf;
140 am
.magic
= RADEON_PRIVATE_DATA_MAGIC
;
141 am
.size
= buffer
->bytes_per_row
* height
;
142 am
.memory_type
= mt_local
;
145 result
= ioctl( ai
->fd
, RADEON_ALLOC_MEM
, &am
);
149 node
->mem_handle
= am
.handle
;
150 node
->mem_offset
= am
.offset
;
151 buffer
->buffer
= si
->local_mem
+ am
.offset
;
152 buffer
->buffer_dma
= (void *) ((unsigned long) si
->framebuffer_pci
+ am
.offset
);
154 // add to list of overlays
155 node
->next
= vc
->overlay_buffers
;
158 node
->next
->prev
= node
;
160 vc
->overlay_buffers
= node
;
162 RELEASE_BEN( si
->engine
.lock
);
164 SHOW_FLOW( 0, "success: mem_handle=%x, offset=%x, CPU-address=%x, phys-address=%x",
165 node
->mem_handle
, node
->mem_offset
, buffer
->buffer
, buffer
->buffer_dma
);
170 RELEASE_BEN( si
->engine
.lock
);
175 // public function: discard overlay buffer
176 status_t
RELEASE_OVERLAY_BUFFER( const overlay_buffer
*ob
)
178 virtual_card
*vc
= ai
->vc
;
179 shared_info
*si
= ai
->si
;
180 overlay_buffer_node
*node
;
186 node
= (overlay_buffer_node
*)((char *)ob
- offsetof( overlay_buffer_node
, buffer
));
188 if( si
->active_overlay
.on
== node
|| si
->active_overlay
.prev_on
)
189 Radeon_HideOverlay( ai
);
192 fm
.magic
= RADEON_PRIVATE_DATA_MAGIC
;
193 fm
.handle
= node
->mem_handle
;
194 fm
.memory_type
= mt_local
;
197 result
= ioctl( ai
->fd
, RADEON_FREE_MEM
, &fm
);
198 if( result
!= B_OK
) {
199 SHOW_FLOW( 3, "ups - couldn't free memory (handle=%x, status=%s)",
200 node
->mem_handle
, strerror( result
));
203 ACQUIRE_BEN( si
->engine
.lock
);
207 node
->next
->prev
= node
->prev
;
210 node
->prev
->next
= node
->next
;
212 vc
->overlay_buffers
= node
->next
;
214 RELEASE_BEN( si
->engine
.lock
);
216 SHOW_FLOW0( 3, "success" );
222 // public function: get constraints of overlay unit
223 status_t
GET_OVERLAY_CONSTRAINTS( const display_mode
*dm
, const overlay_buffer
*ob
,
224 overlay_constraints
*oc
)
228 // probably, this is paranoia as we only get called by app_server
229 // which should know what it's doing
230 if( dm
== NULL
|| ob
== NULL
|| oc
== NULL
)
233 // scaler input restrictions
234 // TBD: check all these values; I reckon that
235 // most of them are too restrictive
238 oc
->view
.h_alignment
= 0;
239 oc
->view
.v_alignment
= 0;
244 oc
->view
.width_alignment
= 7;
247 oc
->view
.width_alignment
= 7;
250 oc
->view
.width_alignment
= 3;
253 oc
->view
.width_alignment
= 7;
256 oc
->view
.width_alignment
= 7;
260 oc
->view
.height_alignment
= 0;
263 oc
->view
.width
.min
= 4; // make 4-tap filter happy
264 oc
->view
.height
.min
= 4;
265 oc
->view
.width
.max
= ob
->width
;
266 oc
->view
.height
.max
= ob
->height
;
268 // scaler output restrictions
269 oc
->window
.h_alignment
= 0;
270 oc
->window
.v_alignment
= 0;
271 oc
->window
.width_alignment
= 0;
272 oc
->window
.height_alignment
= 0;
273 oc
->window
.width
.min
= 2;
274 oc
->window
.width
.max
= dm
->virtual_width
;
275 oc
->window
.height
.min
= 2;
276 oc
->window
.height
.max
= dm
->virtual_height
;
278 // TBD: these values need to be checked
279 // (shamelessly copied from Matrix driver)
280 oc
->h_scale
.min
= 1.0f
/ (1 << 4);
281 oc
->h_scale
.max
= 1 << 12;
282 oc
->v_scale
.min
= 1.0f
/ (1 << 4);
283 oc
->v_scale
.max
= 1 << 12;
285 SHOW_FLOW0( 3, "success" );
291 // public function: allocate overlay unit
292 overlay_token
ALLOCATE_OVERLAY( void )
294 shared_info
*si
= ai
->si
;
295 virtual_card
*vc
= ai
->vc
;
299 if( atomic_or( &si
->overlay_mgr
.inuse
, 1 ) != 0 ) {
300 SHOW_FLOW0( 3, "already in use" );
304 SHOW_FLOW0( 3, "success" );
306 vc
->uses_overlay
= true;
308 return (void *)++si
->overlay_mgr
.token
;
312 // public function: release overlay unit
313 status_t
RELEASE_OVERLAY(overlay_token ot
)
315 virtual_card
*vc
= ai
->vc
;
316 shared_info
*si
= ai
->si
;
320 if( (void *)si
->overlay_mgr
.token
!= ot
)
323 if( si
->overlay_mgr
.inuse
== 0 )
326 if( si
->active_overlay
.on
)
327 Radeon_HideOverlay( ai
);
329 si
->overlay_mgr
.inuse
= 0;
330 vc
->uses_overlay
= false;
332 SHOW_FLOW0( 3, "released" );
338 // public function: show/hide overlay
339 status_t
CONFIGURE_OVERLAY( overlay_token ot
, const overlay_buffer
*ob
,
340 const overlay_window
*ow
, const overlay_view
*ov
)
342 shared_info
*si
= ai
->si
;
347 if ( (uintptr_t)ot
!= si
->overlay_mgr
.token
)
350 if ( !si
->overlay_mgr
.inuse
)
353 if ( ow
== NULL
|| ov
== NULL
) {
354 SHOW_FLOW0( 3, "hide only" );
355 Radeon_HideOverlay( ai
);
362 ACQUIRE_BEN( si
->engine
.lock
);
364 // store whished values
365 si
->pending_overlay
.ot
= ot
;
366 si
->pending_overlay
.ob
= *ob
;
367 si
->pending_overlay
.ow
= *ow
;
368 si
->pending_overlay
.ov
= *ov
;
370 si
->pending_overlay
.on
= (overlay_buffer_node
*)((char *)ob
- offsetof( overlay_buffer_node
, buffer
));
372 result
= Radeon_UpdateOverlay( ai
);
374 RELEASE_BEN( si
->engine
.lock
);