vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / ati / mach64_overlay.cpp
blobdedbaacf01ba894103bd1a2101b96a238ec61f1f
1 /*
2 Haiku ATI video driver adapted from the X.org ATI driver which has the
3 following copyright:
5 Copyright 2003 through 2004 by Marc Aurele La France, tsi@xfree86.org
7 Copyright 2011 Haiku, Inc. All rights reserved.
8 Distributed under the terms of the MIT license.
10 Authors:
11 Gerald Zajac
14 #include "accelerant.h"
15 #include "mach64.h"
19 bool
20 Mach64_DisplayOverlay(const overlay_window* window,
21 const overlay_buffer* buffer)
23 // Return true if setup is successful.
25 SharedInfo& si = *gInfo.sharedInfo;
27 if (window == NULL || buffer == NULL)
28 return false;
30 uint32 videoFormat;
32 if (buffer->space == B_YCbCr422)
33 videoFormat = SCALE_IN_VYUY422;
34 else
35 return false; // color space not supported
37 int32 x1 = (window->h_start < 0) ? 0 : window->h_start;
38 int32 y1 = (window->v_start < 0) ? 0 : window->v_start;
40 int32 x2 = window->h_start + window->width - 1;
41 int32 y2 = window->v_start + window->height - 1;
43 if (x2 > si.displayMode.timing.h_display)
44 x2 = si.displayMode.timing.h_display;
46 if (y2 > si.displayMode.timing.v_display)
47 y2 = si.displayMode.timing.v_display;
49 // If window is moved beyond edge of screen, do not allow width < 4 or
50 // height < 4; otherwise there is a possibilty of divide by zero when
51 // computing the scale factors..
52 if (x2 < x1 + 4)
53 x2 = x1 + 4;
55 if (y2 < y1 + 4)
56 y2 = y1 + 4;
58 // Calculate overlay scale factors.
59 uint32 horzScale = (buffer->width << 12) / (x2 - x1 + 1);
60 uint32 vertScale = (buffer->height << 12) / (y2 - y1 + 1);
62 if (horzScale > 0xffff) // only 16 bits are used for scale factors
63 horzScale = 0xffff;
64 if (vertScale > 0xffff)
65 vertScale = 0xffff;
67 gInfo.WaitForFifo(2);
68 OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_EXT_REG_EN); // enable reg block 1
69 OUTREG(OVERLAY_SCALE_CNTL, SCALE_EN); // reset the video
71 if (si.chipType >= MACH64_264GTPRO) {
72 const uint32 brightness = 0;
73 const uint32 saturation = 12;
75 gInfo.WaitForFifo(6);
76 OUTREG(SCALER_COLOUR_CNTL, brightness | saturation << 8
77 | saturation << 16);
78 OUTREG(SCALER_H_COEFF0, 0x0002000);
79 OUTREG(SCALER_H_COEFF1, 0xd06200d);
80 OUTREG(SCALER_H_COEFF2, 0xd0a1c0d);
81 OUTREG(SCALER_H_COEFF3, 0xc0e1a0c);
82 OUTREG(SCALER_H_COEFF4, 0xc14140c);
85 uint32 keyColor = 0;
86 uint32 keyMask = 0;
88 switch (si.displayMode.bitsPerPixel) {
89 case 15:
90 keyMask = 0x7fff;
91 keyColor = (window->blue.value & window->blue.mask) << 0
92 | (window->green.value & window->green.mask) << 5
93 | (window->red.value & window->red.mask) << 10;
94 // 15 bit color has no alpha bits
95 break;
96 case 16:
97 keyMask = 0xffff;
98 keyColor = (window->blue.value & window->blue.mask) << 0
99 | (window->green.value & window->green.mask) << 5
100 | (window->red.value & window->red.mask) << 11;
101 // 16 bit color has no alpha bits
102 break;
103 default:
104 keyMask = 0xffffffff;
105 keyColor = (window->blue.value & window->blue.mask) << 0
106 | (window->green.value & window->green.mask) << 8
107 | (window->red.value & window->red.mask) << 16
108 | (window->alpha.value & window->alpha.mask) << 24;
109 break;
112 gInfo.WaitForFifo(3);
113 OUTREG(OVERLAY_GRAPHICS_KEY_MSK, keyMask);
114 OUTREG(OVERLAY_GRAPHICS_KEY_CLR, keyColor);
115 OUTREG(OVERLAY_KEY_CNTL, OVERLAY_MIX_FALSE | OVERLAY_MIX_EQUAL);
117 gInfo.WaitForFifo(8);
118 OUTREG(OVERLAY_Y_X_START, OVERLAY_LOCK_START | (x1 << 16) | y1);
119 OUTREG(OVERLAY_Y_X_END, (x2 << 16) | y2);
120 OUTREG(OVERLAY_SCALE_INC, (horzScale << 16) | vertScale);
121 OUTREG(SCALER_HEIGHT_WIDTH, (buffer->width << 16) | buffer->height);
122 OUTREG(VIDEO_FORMAT, videoFormat);
124 // Compute offset of overlay buffer in the video memory.
125 uint32 offset = uint32(buffer->buffer) - si.videoMemAddr;
127 if (si.chipType < MACH64_264VTB) {
128 OUTREG(BUF0_OFFSET, offset);
129 OUTREG(BUF0_PITCH, buffer->width);
130 } else {
131 OUTREG(SCALER_BUF0_OFFSET, offset);
132 OUTREG(SCALER_BUF0_PITCH, buffer->width);
135 OUTREG(OVERLAY_SCALE_CNTL, SCALE_PIX_EXPAND | OVERLAY_EN | SCALE_EN);
137 return true;
141 void
142 Mach64_StopOverlay(void)
144 OUTREG(OVERLAY_SCALE_CNTL, SCALE_EN); // reset the video