vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / ati / rage128_overlay.cpp
blob727fa961fbfae5ede83cf880a1d95b8c415a3a2b
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver which has the
3 following copyright:
5 Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
6 Precision Insight, Inc., Cedar Park, Texas, and
7 VA Linux Systems Inc., Fremont, California.
9 Copyright 2011 Haiku, Inc. All rights reserved.
10 Distributed under the terms of the MIT license.
12 Authors:
13 Gerald Zajac
16 #include "accelerant.h"
17 #include "rage128.h"
20 static uint32 sCurrentKeyColor = 0;
21 static uint32 sCurrentKeyMask = 0;
25 bool
26 Rage128_DisplayOverlay(const overlay_window* window,
27 const overlay_buffer* buffer)
29 // Return true if setup is successful.
31 SharedInfo& si = *gInfo.sharedInfo;
33 if (window == NULL || buffer == NULL)
34 return false;
36 if (buffer->space != B_YCbCr422)
37 return false; // color space not supported
39 uint32 keyColor = 0;
40 uint32 keyMask = 0;
42 switch (si.displayMode.bitsPerPixel) {
43 case 15:
44 keyMask = 0x7fff;
45 keyColor = (window->blue.value & window->blue.mask) << 0
46 | (window->green.value & window->green.mask) << 5
47 | (window->red.value & window->red.mask) << 10;
48 // 15 bit color has no alpha bits
49 break;
50 case 16:
51 keyMask = 0xffff;
52 keyColor = (window->blue.value & window->blue.mask) << 0
53 | (window->green.value & window->green.mask) << 5
54 | (window->red.value & window->red.mask) << 11;
55 // 16 bit color has no alpha bits
56 break;
57 default:
58 keyMask = 0xffffffff;
59 keyColor = (window->blue.value & window->blue.mask) << 0
60 | (window->green.value & window->green.mask) << 8
61 | (window->red.value & window->red.mask) << 16
62 | (window->alpha.value & window->alpha.mask) << 24;
63 break;
66 // If the key color or key mask has changed since the overlay was
67 // previously initialized, initialize it again. This is to avoid
68 // initializing the overlay video everytime the overlay buffer is
69 // switched which causes artifacts in the overlay display.
71 if (keyColor != sCurrentKeyColor || keyMask != sCurrentKeyMask)
73 TRACE("Rage128_DisplayOverlay() initializing overlay video\n");
75 // Initialize the overlay video by first resetting the video.
77 OUTREG(R128_OV0_SCALE_CNTL, 0);
78 OUTREG(R128_OV0_EXCLUSIVE_HORZ, 0);
79 OUTREG(R128_OV0_AUTO_FLIP_CNTL, 0);
80 OUTREG(R128_OV0_FILTER_CNTL, 0x0000000f);
82 const uint32 brightness = 0;
83 const uint32 saturation = 16;
84 OUTREG(R128_OV0_COLOUR_CNTL, brightness | saturation << 8
85 | saturation << 16);
87 OUTREG(R128_OV0_GRAPHICS_KEY_MSK, keyMask);
88 OUTREG(R128_OV0_GRAPHICS_KEY_CLR, keyColor);
89 OUTREG(R128_OV0_KEY_CNTL, R128_GRAPHIC_KEY_FN_NE);
90 OUTREG(R128_OV0_TEST, 0);
92 sCurrentKeyColor = keyColor;
93 sCurrentKeyMask = keyMask;
96 uint32 ecpDiv;
97 if (si.displayMode.timing.pixel_clock < 125000)
98 ecpDiv = 0;
99 else if (si.displayMode.timing.pixel_clock < 250000)
100 ecpDiv = 1;
101 else
102 ecpDiv = 2;
104 SetPLLReg(R128_VCLK_ECP_CNTL, ecpDiv << 8, R128_ECP_DIV_MASK);
106 int32 vertInc = (buffer->height << 20) / window->height;
107 int32 horzInc = (buffer->width << (12 + ecpDiv)) / window->width;
108 int32 stepBy = 1;
110 while (horzInc >= (2 << 12)) {
111 stepBy++;
112 horzInc >>= 1;
115 int32 x1 = window->h_start;
116 int32 y1 = window->v_start;
118 int32 x2 = window->h_start + window->width;
119 int32 y2 = window->v_start + window->height;
121 int32 left = x1;
122 int32 tmp = (left & 0x0003ffff) + 0x00028000 + (horzInc << 3);
123 int32 p1_h_accum_init = ((tmp << 4) & 0x000f8000) |
124 ((tmp << 12) & 0xf0000000);
126 tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (horzInc << 2);
127 int32 p23_h_accum_init = ((tmp << 4) & 0x000f8000) |
128 ((tmp << 12) & 0x70000000);
130 tmp = (y1 & 0x0000ffff) + 0x00018000;
131 int32 p1_v_accum_init = ((tmp << 4) & 0x03ff8000) | 0x00000001;
133 // Compute offset of overlay buffer in the video memory.
134 uint32 offset = uint32(buffer->buffer) - si.videoMemAddr;
136 OUTREG(R128_OV0_REG_LOAD_CNTL, 1);
137 while (!(INREG(R128_OV0_REG_LOAD_CNTL) & (1 << 3)))
140 OUTREG(R128_OV0_H_INC, horzInc | ((horzInc >> 1) << 16));
141 OUTREG(R128_OV0_STEP_BY, stepBy | (stepBy << 8));
142 OUTREG(R128_OV0_Y_X_START, x1 | y1 << 16);
143 OUTREG(R128_OV0_Y_X_END, x2 | y2 << 16);
144 OUTREG(R128_OV0_V_INC, vertInc);
145 OUTREG(R128_OV0_P1_BLANK_LINES_AT_TOP,
146 0x00000fff | ((buffer->height - 1) << 16));
147 OUTREG(R128_OV0_VID_BUF_PITCH0_VALUE, buffer->bytes_per_row);
149 int32 width = window->width;
150 left = 0;
151 OUTREG(R128_OV0_P1_X_START_END, (width - 1) | (left << 16));
152 width >>= 1;
153 OUTREG(R128_OV0_P2_X_START_END, (width - 1) | (left << 16));
154 OUTREG(R128_OV0_P3_X_START_END, (width - 1) | (left << 16));
155 OUTREG(R128_OV0_VID_BUF0_BASE_ADRS, offset);
156 OUTREG(R128_OV0_P1_V_ACCUM_INIT, p1_v_accum_init);
157 OUTREG(R128_OV0_P23_V_ACCUM_INIT, 0);
158 OUTREG(R128_OV0_P1_H_ACCUM_INIT, p1_h_accum_init);
159 OUTREG(R128_OV0_P23_H_ACCUM_INIT, p23_h_accum_init);
161 OUTREG(R128_OV0_SCALE_CNTL, 0x41FF8B03);
162 OUTREG(R128_OV0_REG_LOAD_CNTL, 0);
164 return true;
168 void
169 Rage128_StopOverlay(void)
171 OUTREG(R128_OV0_SCALE_CNTL, 0); // reset the video
173 // Reset the key color and mask so that when the overlay is started again
174 // it will be initialized.
176 sCurrentKeyColor = 0;
177 sCurrentKeyMask = 0;