SDL_fbmatrox.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:7k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. SDL - Simple DirectMedia Layer
  3. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15. Sam Lantinga
  16. slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_fbmatrox.c,v 1.4 2002/04/22 21:38:04 wmay Exp $";
  21. #endif
  22. #include "SDL_types.h"
  23. #include "SDL_video.h"
  24. #include "SDL_blit.h"
  25. #include "SDL_fbmatrox.h"
  26. #include "matrox_mmio.h"
  27. /* Wait for vertical retrace - taken from the XFree86 Matrox driver */
  28. static void WaitVBL(_THIS)
  29. {
  30. int count;
  31. /* find start of retrace */
  32. mga_waitidle();
  33. while (  (mga_in8(0x1FDA) & 0x08) )
  34. ;
  35. while ( !(mga_in8(0x1FDA) & 0x08) )
  36. /* wait until we're past the start */
  37. count = mga_in32(0x1E20) + 2;
  38. while ( mga_in32(0x1E20) < count )
  39. ;
  40. }
  41. static void WaitIdle(_THIS)
  42. {
  43. mga_waitidle();
  44. }
  45. /* Sets video mem colorkey and accelerated blit function */
  46. static int SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key)
  47. {
  48. return(0);
  49. }
  50. /* Sets per surface hardware alpha value */
  51. #if 0
  52. static int SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 value)
  53. {
  54. return(0);
  55. }
  56. #endif
  57. static int FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color)
  58. {
  59. int dstX, dstY;
  60. Uint32 fxbndry;
  61. Uint32 ydstlen;
  62. Uint32 fillop;
  63. /* Don't blit to the display surface when switched away */
  64. if ( dst == this->screen ) {
  65. SDL_mutexP(hw_lock);
  66. }
  67. switch (dst->format->BytesPerPixel) {
  68.     case 1:
  69. color |= (color<<8);
  70.     case 2:
  71. color |= (color<<16);
  72. break;
  73. }
  74. /* Set up the X/Y base coordinates */
  75. FB_dst_to_xy(this, dst, &dstX, &dstY);
  76. /* Adjust for the current rectangle */
  77. dstX += rect->x;
  78. dstY += rect->y;
  79. /* Set up the X boundaries */
  80. fxbndry = (dstX | ((dstX+rect->w) << 16));
  81. /* Set up the Y boundaries */
  82. ydstlen = (rect->h | (dstY << 16));
  83. /* Set up for color fill operation */
  84. fillop = MGADWG_TRAP | MGADWG_SOLID |
  85.          MGADWG_ARZERO | MGADWG_SGNZERO | MGADWG_SHIFTZERO;
  86. /* Execute the operations! */
  87. mga_wait(5);
  88. mga_out32(MGAREG_DWGCTL, fillop | MGADWG_REPLACE);
  89. mga_out32(MGAREG_FCOL, color);
  90. mga_out32(MGAREG_FXBNDRY, fxbndry);
  91. mga_out32(MGAREG_YDSTLEN + MGAREG_EXEC, ydstlen);
  92. FB_AddBusySurface(dst);
  93. if ( dst == this->screen ) {
  94. SDL_mutexV(hw_lock);
  95. }
  96. return(0);
  97. }
  98. static int HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,
  99.                        SDL_Surface *dst, SDL_Rect *dstrect)
  100. {
  101. SDL_VideoDevice *this = current_video;
  102. int pitch, w, h;
  103. int srcX, srcY;
  104. int dstX, dstY;
  105. Uint32 sign;
  106. Uint32 start, stop;
  107. int skip;
  108. Uint32 blitop;
  109. /* FIXME: For now, only blit to display surface */
  110. if ( dst->pitch != SDL_VideoSurface->pitch ) {
  111. return(src->map->sw_blit(src, srcrect, dst, dstrect));
  112. }
  113. /* Don't blit to the display surface when switched away */
  114. if ( dst == this->screen ) {
  115. SDL_mutexP(hw_lock);
  116. }
  117. /* Calculate source and destination base coordinates (in pixels) */
  118. w = dstrect->w;
  119. h = dstrect->h;
  120. FB_dst_to_xy(this, src, &srcX, &srcY);
  121. FB_dst_to_xy(this, dst, &dstX, &dstY);
  122. /* Adjust for the current blit rectangles */
  123. srcX += srcrect->x;
  124. srcY += srcrect->y;
  125. dstX += dstrect->x;
  126. dstY += dstrect->y;
  127. pitch = dst->pitch/dst->format->BytesPerPixel;
  128. /* Set up the blit direction (sign) flags */
  129. sign = 0;
  130. if ( srcX < dstX ) {
  131. sign |= 1;
  132. }
  133. if ( srcY < dstY ) {
  134. sign |= 4;
  135. srcY += (h - 1);
  136. dstY += (h - 1);
  137. }
  138. /* Set up the blit source row start, end, and skip (in pixels) */
  139. stop = start = (srcY * pitch) + srcX;
  140. if ( srcX < dstX ) {
  141. start += (w - 1);
  142. } else {
  143. stop  += (w - 1);
  144. }
  145. if ( srcY < dstY ) {
  146. skip = -pitch;
  147. } else {
  148. skip = pitch;
  149. }
  150. /* Set up the blit operation */
  151. if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
  152. Uint32 colorkey;
  153. blitop = MGADWG_BFCOL | MGADWG_BITBLT |
  154.          MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16) |
  155.          MGADWG_TRANSC;
  156. colorkey = src->format->colorkey;
  157. switch (dst->format->BytesPerPixel) {
  158.     case 1:
  159. colorkey |= (colorkey<<8);
  160.     case 2:
  161. colorkey |= (colorkey<<16);
  162. break;
  163. }
  164. mga_wait(2);
  165. mga_out32(MGAREG_FCOL, colorkey);
  166. mga_out32(MGAREG_BCOL, 0xFFFFFFFF);
  167. } else {
  168. blitop = MGADWG_BFCOL | MGADWG_BITBLT |
  169.          MGADWG_SHIFTZERO | MGADWG_RSTR | (0x0C << 16);
  170. }
  171. mga_wait(7);
  172. mga_out32(MGAREG_SGN, sign);
  173. mga_out32(MGAREG_AR3, start);
  174. mga_out32(MGAREG_AR0, stop);
  175. mga_out32(MGAREG_AR5, skip);
  176. mga_out32(MGAREG_FXBNDRY, (dstX | ((dstX + w-1) << 16)));
  177. mga_out32(MGAREG_YDSTLEN, (dstY << 16) | h);
  178. mga_out32(MGAREG_DWGCTL + MGAREG_EXEC, blitop);
  179. FB_AddBusySurface(src);
  180. FB_AddBusySurface(dst);
  181. if ( dst == this->screen ) {
  182. SDL_mutexV(hw_lock);
  183. }
  184. return(0);
  185. }
  186. static int CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst)
  187. {
  188. int accelerated;
  189. /* Set initial acceleration on */
  190. src->flags |= SDL_HWACCEL;
  191. /* Set the surface attributes */
  192. if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
  193. if ( ! this->info.blit_hw_A ) {
  194. src->flags &= ~SDL_HWACCEL;
  195. }
  196. }
  197. if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {
  198. if ( ! this->info.blit_hw_CC ) {
  199. src->flags &= ~SDL_HWACCEL;
  200. }
  201. }
  202. /* Check to see if final surface blit is accelerated */
  203. accelerated = !!(src->flags & SDL_HWACCEL);
  204. if ( accelerated ) {
  205. src->map->hw_blit = HWAccelBlit;
  206. }
  207. return(accelerated);
  208. }
  209. void FB_MatroxAccel(_THIS, __u32 card)
  210. {
  211. /* We have hardware accelerated surface functions */
  212. this->CheckHWBlit = CheckHWBlit;
  213. wait_vbl = WaitVBL;
  214. wait_idle = WaitIdle;
  215. /* The Matrox has an accelerated color fill */
  216. this->info.blit_fill = 1;
  217. this->FillHWRect = FillHWRect;
  218. /* The Matrox has accelerated normal and colorkey blits. */
  219. this->info.blit_hw = 1;
  220. /* The Millenium I appears to do the colorkey test a word
  221.    at a time, and the transparency is intverted. (?)
  222.  */
  223. if ( card != FB_ACCEL_MATROX_MGA2064W ) {
  224. this->info.blit_hw_CC = 1;
  225. this->SetHWColorKey = SetHWColorKey;
  226. }
  227. #if 0 /* Not yet implemented? */
  228. /* The Matrox G200/G400 has an accelerated alpha blit */
  229. if ( (card == FB_ACCEL_MATROX_MGAG200)
  230.   || (card == FB_ACCEL_MATROX_MGAG400)
  231. ) {
  232. this->info.blit_hw_A = 1;
  233. this->SetHWAlpha = SetHWAlpha;
  234. }
  235. #endif
  236. }