2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
8 #include <aros/debug.h>
9 #include <aros/libcall.h>
10 #include <aros/asmcall.h>
11 #include <aros/symbolsets.h>
12 #include <utility/tagitem.h>
13 #include <hidd/graphics.h>
15 #include <proto/oop.h>
16 #include <proto/exec.h>
17 #include <proto/utility.h>
22 #include "intelG45_intern.h"
23 #include "intelG45_regs.h"
24 #include "compositing.h"
26 struct __ROP ROP_table
[] = {
27 { ROP3_ZERO
, ROP3_ZERO
}, /* GXclear */
28 { ROP3_DSa
, ROP3_DPa
}, /* Gxand */
29 { ROP3_SDna
, ROP3_PDna
}, /* GXandReverse */
30 { ROP3_S
, ROP3_P
}, /* GXcopy */
31 { ROP3_DSna
, ROP3_DPna
}, /* GXandInverted */
32 { ROP3_D
, ROP3_D
}, /* GXnoop */
33 { ROP3_DSx
, ROP3_DPx
}, /* GXxor */
34 { ROP3_DSo
, ROP3_DPo
}, /* GXor */
35 { ROP3_DSon
, ROP3_DPon
}, /* GXnor */
36 { ROP3_DSxn
, ROP3_PDxn
}, /* GXequiv */
37 { ROP3_Dn
, ROP3_Dn
}, /* GXinvert */
38 { ROP3_SDno
, ROP3_PDno
}, /* GXorReverse */
39 { ROP3_Sn
, ROP3_Pn
}, /* GXcopyInverted */
40 { ROP3_DSno
, ROP3_DPno
}, /* GXorInverted */
41 { ROP3_DSan
, ROP3_DPan
}, /* GXnand */
42 { ROP3_ONE
, ROP3_ONE
} /* GXset */
45 #define sd ((struct g45staticdata*)SD(cl))
47 #define POINT_OUTSIDE_CLIP(gc, x, y) \
48 ( (x) < GC_CLIPX1(gc) \
49 || (x) > GC_CLIPX2(gc) \
50 || (y) < GC_CLIPY1(gc) \
51 || (y) > GC_CLIPY2(gc) )
53 static BOOL
CanAccelerateBlits(UWORD product_id
)
55 return product_id
>= 0x2582
56 && product_id
<= 0x27ae;
59 OOP_Object
*METHOD(GMABM
, Root
, New
)
61 EnterFunc(bug("[GMABitMap] Bitmap::New()\n"));
63 o
= (OOP_Object
*)OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
66 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
68 IPTR width
, height
, depth
;
74 InitSemaphore(&bm
->bmLock
);
76 D(bug("[GMABitMap] Super called. o=%p\n", o
));
78 OOP_GetAttr(o
, aHidd_BitMap_Width
, &width
);
79 OOP_GetAttr(o
, aHidd_BitMap_Height
, &height
);
80 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&pf
);
81 OOP_GetAttr(pf
, aHidd_PixFmt_Depth
, &depth
);
82 OOP_GetAttr(o
, aHidd_BitMap_Displayable
, &displayable
);
84 bm
->onbm
= displayable
;
86 D(bug("[GMABitmap] width=%d height=%d depth=%d\n", width
, height
, depth
));
88 if (width
== 0 || height
== 0 || depth
== 0)
90 bug("[GMABitMap] size mismatch!\n");
105 bm
->pitch
= (width
* bytesPerPixel
+ 63) & ~63;
107 bm
->bpp
= bytesPerPixel
;
108 bm
->framebuffer
= AllocBitmapArea(sd
, bm
->width
, bm
->height
, bm
->bpp
);
115 bm
->fbid
= 0; /* Default value */
117 if (displayable
) bm
->displayable
= TRUE
; else bm
->displayable
= FALSE
;
118 //bm->compositing = sd->compositing;
119 bm
->compositing
= (OOP_Object
*)
120 GetTagData(aHidd_BitMap_IntelG45_CompositingHidd
, 0, msg
->attrList
);
121 /* FIXME: check if compositing hidd was passed */
125 if ((bm
->framebuffer
!= -1))
132 /* We should be able to get modeID from the bitmap */
133 OOP_GetAttr(o
, aHidd_BitMap_ModeID
, &modeid
);
135 D(bug("[GMABitMap] BM_ModeID=%x\n", modeid
));
137 if (modeid
!= vHidd_ModeID_Invalid
)
140 IPTR hdisp
, vdisp
, hstart
, hend
, htotal
, vstart
, vend
, vtotal
, flags
;
142 /* Get Sync and PixelFormat properties */
143 struct pHidd_Gfx_GetMode __getmodemsg
= {
147 }, *getmodemsg
= &__getmodemsg
;
149 getmodemsg
->mID
= OOP_GetMethodID((STRPTR
)CLID_Hidd_Gfx
, moHidd_Gfx_GetMode
);
150 OOP_DoMethod(sd
->GMAObject
, (OOP_Msg
)getmodemsg
);
152 OOP_GetAttr(sync
, aHidd_Sync_PixelClock
, &pixel
);
153 OOP_GetAttr(sync
, aHidd_Sync_HDisp
, &hdisp
);
154 OOP_GetAttr(sync
, aHidd_Sync_VDisp
, &vdisp
);
155 OOP_GetAttr(sync
, aHidd_Sync_HSyncStart
, &hstart
);
156 OOP_GetAttr(sync
, aHidd_Sync_VSyncStart
, &vstart
);
157 OOP_GetAttr(sync
, aHidd_Sync_HSyncEnd
, &hend
);
158 OOP_GetAttr(sync
, aHidd_Sync_VSyncEnd
, &vend
);
159 OOP_GetAttr(sync
, aHidd_Sync_HTotal
, &htotal
);
160 OOP_GetAttr(sync
, aHidd_Sync_VTotal
, &vtotal
);
161 OOP_GetAttr(sync
, aHidd_Sync_Flags
, &flags
);
163 bm
->state
= (GMAState_t
*)AllocVecPooled(sd
->MemPool
,
170 G45_InitMode(sd
, bm
->state
, width
, height
, depth
, pixel
, bm
->framebuffer
,
172 hstart
, hend
, htotal
,
173 vstart
, vend
, vtotal
, flags
);
175 D(bug("[GMA] displayable Bitmap::new = %p\n", o
));
183 bm
->framebuffer
= (IPTR
)AllocMem(bm
->pitch
* bm
->height
,
184 MEMF_PUBLIC
| MEMF_CLEAR
);
192 if (bm
->framebuffer
== -1)
194 bm
->framebuffer
= (IPTR
)AllocMem(bm
->pitch
* bm
->height
,
195 MEMF_PUBLIC
| MEMF_CLEAR
);
199 if (bm
->framebuffer
!= 0)
201 D(bug("[GMA] not displayable Bitmap::new = %p\n", o
));
206 OOP_MethodID disp_mid
= OOP_GetMethodID((STRPTR
)IID_Root
, moRoot_Dispose
);
207 OOP_CoerceMethod(cl
, o
, (OOP_Msg
) &disp_mid
);
214 VOID
METHOD(GMABM
, Root
, Dispose
)
216 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
225 FreeBitmapArea(sd
, bm
->framebuffer
, bm
->width
, bm
->height
, bm
->bpp
);
227 if (sd
->VisibleBitmap
== bm
)
229 sd
->VisibleBitmap
= NULL
;
232 bm
->framebuffer
= -1;
236 FreeMem((APTR
)bm
->framebuffer
, bm
->pitch
* bm
->height
);
239 FreeVecPooled(sd
->MemPool
, bm
->state
);
244 RADEONWaitForIdleMMIO(sd
);
247 FreeVecPooled(sd
->memPool
, bm
->addresses
);
254 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
257 VOID
METHOD(GMABM
, Root
, Get
)
259 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
262 if (IS_GMABM_ATTR(msg
->attrID
, idx
))
266 case aoHidd_GMABitMap_Drawable
:
268 *msg
->storage
= bm
->framebuffer
+ (IPTR
)sd
->Card
.Framebuffer
;
270 *msg
->storage
= bm
->framebuffer
;
273 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
278 if (IS_BM_ATTR(msg
->attrID
, idx
))
282 case aoHidd_BitMap_LeftEdge
:
283 *msg
->storage
= bm
->xoffset
;
285 case aoHidd_BitMap_TopEdge
:
286 *msg
->storage
= bm
->yoffset
;
291 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
295 VOID
METHOD(GMABM
, Root
, Set
)
297 struct TagItem
*tag
, *tstate
;
298 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, o
);
300 LONG newxoffset
= bmdata
->xoffset
;
301 LONG newyoffset
= bmdata
->yoffset
;
302 tstate
= msg
->attrList
;
303 while((tag
= NextTagItem(&tstate
)))
305 if(IS_BITMAP_ATTR(tag
->ti_Tag
, idx
))
309 case aoHidd_BitMap_LeftEdge
:
310 newxoffset
= tag
->ti_Data
;
312 case aoHidd_BitMap_TopEdge
:
313 newyoffset
= tag
->ti_Data
;
319 /* If there was a change requested, validate it */
320 struct pHidd_Compositing_ValidateBitMapPositionChange vbpcmsg
=
322 mID
: SD(cl
)->mid_ValidateBitMapPositionChange
,
324 newxoffset
: &newxoffset
,
325 newyoffset
: &newyoffset
328 OOP_DoMethod(bmdata
->compositing
, (OOP_Msg
)&vbpcmsg
);
330 if ((newxoffset
!= bmdata
->xoffset
) || (newyoffset
!= bmdata
->yoffset
))
332 /* If change passed validation, execute it */
333 struct pHidd_Compositing_BitMapPositionChanged bpcmsg
=
335 mID
: SD(cl
)->mid_BitMapPositionChanged
,
339 bmdata
->xoffset
= newxoffset
;
340 bmdata
->yoffset
= newyoffset
;
342 OOP_DoMethod(bmdata
->compositing
, (OOP_Msg
)&bpcmsg
);
345 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
350 static inline void setup_engine(OOP_Class *cl, OOP_Object *o, GMABitMap_t *bm)
352 if (sd->Engine2DOwner != bm && bm->fbgfx)
358 OUT_RING((2 << 29) | (0x11 << 22) | (7)); // BR00
360 OUT_RING(0xff << 16 | bm->pitch/4);
361 else if (bm->bpp == 2)
362 OUT_RING(0xff << 16 | (bm->pitch / 4) | (1 << 24));
364 OUT_RING(0xff << 16 | (bm->pitch / 4) | (3 << 24));
367 OUT_RING(bm->framebuffer);
372 sd->Engine2DOwner = bm;
379 VOID
METHOD(GMABM
, Hidd_BitMap
, PutPixel
)
381 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
384 // if (msg->x >= 0 && msg->x < bm->width && msg->y >= 0 && msg->y < bm->height)
396 ptr
= (void *)(bm
->framebuffer
+ sd
->Card
.Framebuffer
+ msg
->y
* bm
->pitch
);
398 ptr
= (void *)(bm
->framebuffer
+ msg
->y
* bm
->pitch
);
404 ((UBYTE
*)ptr
)[msg
->x
] = msg
->pixel
;
407 ((UWORD
*)ptr
)[msg
->x
] = msg
->pixel
;
410 ((ULONG
*)ptr
)[msg
->x
] = msg
->pixel
;
418 HIDDT_Pixel
METHOD(GMABM
, Hidd_BitMap
, GetPixel
)
420 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
422 HIDDT_Pixel pixel
= 0;
434 ptr
= sd
->Card
.Framebuffer
;
437 ptr
+= bm
->framebuffer
+ msg
->y
* bm
->pitch
;
442 pixel
= ((UBYTE
*)ptr
)[msg
->x
];
445 pixel
= ((UWORD
*)ptr
)[msg
->x
];
448 pixel
= ((ULONG
*)ptr
)[msg
->x
];
457 VOID
METHOD(GMABM
, Hidd_BitMap
, DrawPixel
)
459 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
461 OOP_Object
*gc
= msg
->gc
;
463 HIDDT_Pixel src
, dest
= 0, val
;
465 HIDDT_Pixel writeMask
;
468 ptr
= sd
->Card
.Framebuffer
;
471 ptr
+= bm
->framebuffer
+ msg
->y
* bm
->pitch
;
485 if (vHidd_GC_DrawMode_Copy
== mode
&& GC_COLMASK(gc
) == ~0)
494 dest
= ((UBYTE
*)ptr
)[msg
->x
];
497 dest
= ((UWORD
*)ptr
)[msg
->x
];
500 dest
= ((ULONG
*)ptr
)[msg
->x
];
504 writeMask
= ~GC_COLMASK(gc
) & dest
;
508 if(mode
& 1) val
= ( src
& dest
);
509 if(mode
& 2) val
= ( src
& ~dest
) | val
;
510 if(mode
& 4) val
= (~src
& dest
) | val
;
511 if(mode
& 8) val
= (~src
& ~dest
) | val
;
513 val
= (val
& (writeMask
| GC_COLMASK(gc
) )) | writeMask
;
526 ((UBYTE
*)ptr
)[msg
->x
] = val
;
529 ((UWORD
*)ptr
)[msg
->x
] = val
;
532 ((ULONG
*)ptr
)[msg
->x
] = val
;
539 VOID
METHOD(GMABM
, Hidd_BitMap
, DrawEllipse
)
541 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
542 OOP_Object
*gc
= msg
->gc
;
543 WORD x
= msg
->rx
, y
= 0; /* ellipse points */
547 /* intermediate terms to speed up loop */
548 LONG t1
= msg
->rx
* msg
->rx
, t2
= t1
<< 1, t3
= t2
<< 1;
549 LONG t4
= msg
->ry
* msg
->ry
, t5
= t4
<< 1, t6
= t5
<< 1;
550 LONG t7
= msg
->rx
* t5
, t8
= t7
<< 1, t9
= 0L;
551 LONG d1
= t2
- t7
+ (t4
>> 1); /* error terms */
552 LONG d2
= (t1
>> 1) - t8
+ t5
;
554 APTR doclip
= GC_DOCLIP(gc
);
559 void _drawpixel(int x
, int y
)
561 OUT_RING((2 << 29) | (0x24 << 22) );
562 OUT_RING((y
<< 16) | x
);
572 uint32_t br00
, br01
, br24
, br25
, br09
, br05
, br06
, br07
;
574 br00
= (2 << 29) | (0x1 << 22) | 6;
579 br01
= ROP_table
[mode
].pattern
| (bm
->pitch
);
582 else if (bm
->bpp
== 2)
588 br24
= GC_CLIPX1(gc
) | (GC_CLIPY1(gc
) << 16);
589 br25
= (GC_CLIPX2(gc
)+1) | ((GC_CLIPY2(gc
)+1) << 16);
590 br09
= bm
->framebuffer
;
606 while (d2
< 0) /* til slope = -1 */
608 /* draw 4 points using symmetry */
613 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
614 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
615 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
616 _drawpixel(msg
->x
- x
, msg
->y
- y
);
621 y
++; /* always move up here */
623 if (d1
< 0) /* move straight up */
628 else /* move up and left */
632 d1
= d1
+ t9
+ t2
- t8
;
633 d2
= d2
+ t9
+ t5
- t8
;
637 do /* rest of top right quadrant */
639 /* draw 4 points using symmetry */
643 _drawpixel(msg
->x
+ x
, msg
->y
+ y
);
644 _drawpixel(msg
->x
+ x
, msg
->y
- y
);
645 _drawpixel(msg
->x
- x
, msg
->y
+ y
);
646 _drawpixel(msg
->x
- x
, msg
->y
- y
);
651 x
--; /* always move left here */
653 if (d2
< 0) /* move up and left */
657 d2
= d2
+ t9
+ t5
- t8
;
659 else /* move straight left */
669 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
674 VOID
METHOD(GMABM
, Hidd_BitMap
, DrawLine
)
676 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
677 OOP_Object
*gc
= msg
->gc
;
681 WORD dx
, dy
, incrE
, incrNE
, d
, x
, y
, s1
, s2
, t
, i
;
684 APTR doclip
= GC_DOCLIP(gc
);
689 void _drawpixel(int x
, int y
)
691 OUT_RING((2 << 29) | (0x24 << 22) );
692 OUT_RING((y
<< 16) | x
);
697 /* If line is not inside cliprect, then just return */
698 /* Normalize coords */
699 if (msg
->x1
> msg
->x2
)
701 x1
= msg
->x2
; x2
= msg
->x1
;
705 x1
= msg
->x1
; x2
= msg
->x2
;
708 if (msg
->y1
> msg
->y2
)
710 y1
= msg
->y2
; y2
= msg
->y1
;
714 y1
= msg
->y1
; y2
= msg
->y2
;
717 if ( x1
> GC_CLIPX2(gc
)
718 || x2
< GC_CLIPX1(gc
)
719 || y1
> GC_CLIPY2(gc
)
720 || y2
< GC_CLIPY1(gc
) )
723 /* Line is not inside cliprect, so just return */
736 if ((GC_LINEPAT(gc
) != (UWORD
)~0) || !bm
->fbgfx
)
738 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
744 uint32_t br00
, br01
, br24
, br25
, br09
, br05
, br06
, br07
;
747 br00
= (2 << 29) | (0x1 << 22) | 6;
752 br01
= ROP_table
[mode
].pattern
| (bm
->pitch
);
755 else if (bm
->bpp
== 2)
761 br24
= GC_CLIPX1(gc
) | (GC_CLIPY1(gc
) << 16);
762 br25
= (GC_CLIPX2(gc
)+1) | ((GC_CLIPY2(gc
)+1) << 16);
763 br09
= bm
->framebuffer
;
782 Horizontal line drawing code.
786 /* Don't swap coordinates if x2 < x1! Because of linepattern! */
799 ring_space
= x2
-x1
+1;
800 if (ring_space
> 500)
803 START_RING(ring_space
);
805 for(i
= x1
; i
!= x2
; i
+= dx
)
814 if (ring_space
> 500)
816 START_RING(ring_space
);
823 Vertical line drawing code.
827 /* Don't swap coordinates if y2 < y1! Because of linepattern! */
840 ring_space
= y2
-y1
+1;
841 if (ring_space
> 500)
844 START_RING(ring_space
);
846 for(i
= y1
; i
!= y2
; i
+= dy
)
855 if (ring_space
> 500)
857 START_RING(ring_space
);
864 Generic line drawing code.
866 /* Calculate slope */
870 /* which direction? */
871 if((x2
- x1
) > 0) s1
= 1; else s1
= - 1;
872 if((y2
- y1
) > 0) s2
= 1; else s2
= - 1;
874 /* change axes if dx < dy */
887 d
= 2 * dy
- dx
; /* initial value of d */
889 incrE
= 2 * dy
; /* Increment use for move to E */
890 incrNE
= 2 * (dy
- dx
); /* Increment use for move to NE */
895 if (ring_space
> 500)
898 START_RING(ring_space
);
900 for(i
= 0; i
<= dx
; i
++)
910 if (ring_space
> 500)
912 START_RING(ring_space
);
946 ULONG
METHOD(GMABM
, Hidd_BitMap
, BytesPerLine
)
948 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
953 BOOL
METHOD(GMABM
, Hidd_BitMap
, ObtainDirectAccess
)
955 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
957 IPTR VideoData
= bm
->framebuffer
;
960 VideoData
+= (IPTR
)sd
->Card
.Framebuffer
;
965 *msg
->addressReturn
= (UBYTE
*)VideoData
;
966 *msg
->widthReturn
= bm
->pitch
/ bm
->bpp
;
967 *msg
->heightReturn
= bm
->height
;
968 *msg
->bankSizeReturn
= *msg
->memSizeReturn
= bm
->pitch
* bm
->height
;
972 VOID
METHOD(GMABM
, Hidd_BitMap
, ReleaseDirectAccess
)
975 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
980 struct pHidd_Compositing_BitMapRectChanged brcmsg
=
982 mID
: SD(cl
)->mid_BitMapRectChanged
,
989 OOP_DoMethod(bm
->compositing
, (OOP_Msg
)&brcmsg
);
994 #define pHidd_BitMap_FillRect pHidd_BitMap_DrawRect
996 VOID
METHOD(GMABM
, Hidd_BitMap
, FillRect
)
998 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1006 uint32_t br00
,br13
,br14
,br09
,br16
;
1008 br00
= (2 << 29) | (0x40 << 22) | 3;
1013 br13
= (ROP_table
[GC_DRMD(msg
->gc
)].pattern
) | (bm
->pitch
);
1026 br14
= ((msg
->maxY
- msg
->minY
+1) << 16) | ((msg
->maxX
- msg
->minX
+1) * bm
->bpp
);
1028 br09
= bm
->framebuffer
+ msg
->minX
* bm
->bpp
+ msg
->minY
* bm
->pitch
;
1029 br16
= GC_FG(msg
->gc
);
1044 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
) msg
);
1049 /* Unaccelerated functions */
1051 static inline int do_alpha(int a
, int v
)
1054 return ((tmp
<< 8) + tmp
+ 32768) >> 16;
1058 the BLT engine (the blitter) can not do alpha blending,
1059 however we may utilise the 3d engine in future ..
1061 VOID
METHOD(GMABM
, Hidd_BitMap
, PutAlphaImage
)
1063 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1068 VideoData
= bm
->framebuffer
;
1070 if ((bm
->fbgfx
) && ((bm
->bpp
== 2) || (bm
->bpp
== 4)))
1072 ULONG
*pixarray
, *pasrc
= (ULONG
*)msg
->pixels
;
1073 ULONG srcpix
, x
, y
= msg
->y
;
1074 LONG src_red
, src_green
, src_blue
, src_alpha
;
1075 LONG dst_red
, dst_green
, dst_blue
;
1076 UWORD height
= msg
->height
;
1077 UWORD bw
= msg
->width
;
1079 /* Since we wont use the BLT engine now, flush the chip */
1085 * Treat each depth case separately
1089 ULONG
*xbuf
= (ULONG
*)(VideoData
+ sd
->Card
.Framebuffer
+ (msg
->x
<< 2) + (y
* bm
->pitch
));
1095 for (x
=0; x
< bw
; x
++)
1097 /* Read RGBA pixel from input array */
1098 srcpix
= *pixarray
++;
1100 src_red
= (srcpix
& 0x00FF0000) >> 16;
1101 src_green
= (srcpix
& 0x0000FF00) >> 8;
1102 src_blue
= (srcpix
& 0x000000FF);
1103 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1105 src_red
= (srcpix
& 0x0000FF00) >> 8;
1106 src_green
= (srcpix
& 0x00FF0000) >> 16;
1107 src_blue
= (srcpix
& 0xFF000000) >> 24;
1108 src_alpha
= (srcpix
& 0x000000FF);
1111 * If the pixel is Opaque (alpha=0), skip unnecessary
1112 * reads and writes to VRAM.
1116 if (src_alpha
== 0xff)
1118 /* Fully Transparent, just copy the source pixel */
1120 dst_green
= src_green
;
1121 dst_blue
= src_blue
;
1125 /* Alpha blend the source and destination pixels */
1127 //#if AROS_BIG_ENDIAN
1128 // dst_red = (destpix & 0x0000FF00) >> 8;
1129 // dst_green = (destpix & 0x00FF0000) >> 16;
1130 // dst_blue = (destpix & 0xFF000000) >> 24;
1132 dst_red
= (destpix
& 0x00FF0000) >> 16;
1133 dst_green
= (destpix
& 0x0000FF00) >> 8;
1134 dst_blue
= (destpix
& 0x000000FF);
1137 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1138 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1139 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1142 //#if AROS_BIG_ENDIAN
1143 // destpix = (dst_blue << 24) + (dst_green << 16) + (dst_red << 8);
1145 destpix
= (dst_red
<< 16) + (dst_green
<< 8) + (dst_blue
);
1147 /* Store the new pixel */
1153 pasrc
= (ULONG
*)((IPTR
)pasrc
+ msg
->modulo
);
1154 xbuf
= (ULONG
*)((IPTR
)xbuf
+ bm
->pitch
);
1159 UWORD
*xbuf
= (UWORD
*)(VideoData
+ sd
->Card
.Framebuffer
+ (msg
->x
<< 1) + (y
* bm
->pitch
));
1165 for (x
=0; x
< bw
; x
++)
1167 srcpix
= *pixarray
++;
1169 src_red
= (srcpix
& 0x00FF0000) >> 16;
1170 src_green
= (srcpix
& 0x0000FF00) >> 8;
1171 src_blue
= (srcpix
& 0x000000FF);
1172 src_alpha
= (srcpix
& 0xFF000000) >> 24;
1174 src_red
= (srcpix
& 0x0000FF00) >> 8;
1175 src_green
= (srcpix
& 0x00FF0000) >> 16;
1176 src_blue
= (srcpix
& 0xFF000000) >> 24;
1177 src_alpha
= (srcpix
& 0x000000FF);
1179 /* If Opaque, skip unnecessary reads and writes to VRAM. */
1182 if (src_alpha
== 0xff)
1184 /* Fully Transparent */
1186 dst_green
= src_green
;
1187 dst_blue
= src_blue
;
1195 dst_red
= (destpix
& 0x0000F800) >> 8;
1196 dst_green
= (destpix
& 0x000007e0) >> 3;
1197 dst_blue
= (destpix
& 0x0000001f) << 3;
1199 dst_red
+= do_alpha(src_alpha
, src_red
- dst_red
);
1200 dst_green
+= do_alpha(src_alpha
, src_green
- dst_green
);
1201 dst_blue
+= do_alpha(src_alpha
, src_blue
- dst_blue
);
1204 destpix
= (((dst_red
<< 8) & 0xf800) | ((dst_green
<< 3) & 0x07e0) | ((dst_blue
>> 3) & 0x001f));
1210 pasrc
= (ULONG
*)((IPTR
)pasrc
+ msg
->modulo
);
1211 xbuf
= (UWORD
*)((IPTR
)xbuf
+ bm
->pitch
);
1216 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1221 VOID
METHOD(GMABM
, Hidd_BitMap
, PutImage
)
1223 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1228 IPTR VideoData
= bm
->framebuffer
;
1230 /* In 32bpp mode the StdPixFmt_Native format bitmap can be drawn using the 2D engine.
1231 * This is done by mapping the source range via GTT into video space and issuing the blit.
1233 * Unfortunately, AROS likes to re-use the same scratch line many times during one single bitmap
1234 * draw (many blits of height=1 instead of one single blit).
1235 * Therefore, many many the cache flushes kill the expected performance significantly. */
1237 if (CanAccelerateBlits(sd
->ProductID
) && bm
->fbgfx
&& bm
->bpp
== 4
1238 && (msg
->pixFmt
== vHidd_StdPixFmt_Native
1239 || msg
->pixFmt
== vHidd_StdPixFmt_Native32
1240 || msg
->pixFmt
== vHidd_StdPixFmt_BGRA32
1241 || msg
->pixFmt
== vHidd_StdPixFmt_BGR032
))
1243 UBYTE
*src
= msg
->pixels
;
1244 ULONG x_add
= msg
->modulo
;
1245 UWORD height
= msg
->height
;
1252 intptr_t length
= x_add
* height
;
1253 intptr_t phys
= ((intptr_t)src
) & 0xfffff000;
1254 length
+= (intptr_t)src
- phys
;
1256 length
= (length
+ 4095) & ~4095;
1258 if (length
<= 16*1024*1024)
1260 intptr_t virt
= sd
->ScratchArea
+ ((intptr_t)src
- phys
);
1263 //D(bug("[GMA] PutImage(%d, %d, fmt=%d) with buffer at %p\n", msg->width, msg->height, msg->pixFmt,phys));
1265 if (sd
->AttachedMemory
!= phys
|| sd
->AttachedSize
!= length
)
1267 G45_AttachCacheableMemory(sd
, phys
, sd
->ScratchArea
, length
);
1268 sd
->AttachedMemory
= phys
;
1269 sd
->AttachedSize
= length
;
1272 writel(0, &sd
->HardwareStatusPage
[16]);
1274 uint32_t br00
, br13
, br14
, br09
, br11
, br12
;
1276 br00
= (2 << 29) | (0x43 << 22) | (4);
1279 br13
= bm
->pitch
| ROP3_S
;
1282 br14
= (msg
->width
* bm
->bpp
) | (msg
->height
) << 16;
1283 br09
= bm
->framebuffer
+ bm
->pitch
* msg
->y
+ bm
->bpp
* msg
->x
;
1296 OUT_RING((4 << 23));
1299 OUT_RING((0x21 << 23) | 1);
1308 /* Wait until HW is ready with blit and flush */
1309 while(readl(&sd
->HardwareStatusPage
[16]) == 0);
1314 D(bug("[GMA] PutImage on unknown pixfmt %d\n",msg
->pixFmt
));
1318 VideoData
+= (IPTR
)sd
->Card
.Framebuffer
;
1327 case vHidd_StdPixFmt_Native
:
1332 struct pHidd_BitMap_CopyMemBox8 __m
= {
1333 sd
->mid_CopyMemBox8
,
1346 OOP_DoMethod(o
, (OOP_Msg
)m
);
1352 struct pHidd_BitMap_CopyMemBox16 __m
= {
1353 sd
->mid_CopyMemBox16
,
1366 OOP_DoMethod(o
, (OOP_Msg
)m
);
1372 struct pHidd_BitMap_CopyMemBox32 __m
= {
1373 sd
->mid_CopyMemBox32
,
1386 OOP_DoMethod(o
, (OOP_Msg
)m
);
1390 } /* switch(data->bytesperpix) */
1393 case vHidd_StdPixFmt_Native32
:
1398 struct pHidd_BitMap_PutMem32Image8 __m
= {
1399 sd
->mid_PutMem32Image8
,
1409 OOP_DoMethod(o
, (OOP_Msg
)m
);
1415 struct pHidd_BitMap_PutMem32Image16 __m
= {
1416 sd
->mid_PutMem32Image16
,
1426 OOP_DoMethod(o
, (OOP_Msg
)m
);
1432 struct pHidd_BitMap_CopyMemBox32 __m
= {
1433 sd
->mid_CopyMemBox32
,
1446 OOP_DoMethod(o
, (OOP_Msg
)m
);
1450 } /* switch(data->bytesperpix) */
1454 if (CanAccelerateBlits(sd
->ProductID
) && bm
->bpp
== 4)
1456 /* Get image width aligned to 4K page boundary */
1457 uint32_t line_width
= (msg
->width
* bm
->bpp
+ 4095) & ~4095;
1458 void *pages
= AllocVecPooled(sd
->MemPool
, line_width
* 5);
1464 /* Get two buffers in different GTT regions and _surely_ in different CPU cache lines */
1465 uint32_t *buffer_1
= (uint32_t *)(((intptr_t)pages
+ 4095) & ~4095);
1466 uint32_t *buffer_2
= &buffer_1
[line_width
/ 4];
1467 uint32_t *buffer_3
= &buffer_2
[line_width
/ 4];
1468 uint32_t *buffer_4
= &buffer_3
[line_width
/ 4];
1471 const uint32_t height
= msg
->height
;
1472 uint8_t *src
= msg
->pixels
;
1473 uint32_t x_add
= msg
->modulo
;
1475 D(bug("[GMA] Unknown PutImage(%d, %d) with buffers at %p\n", msg
->width
, msg
->height
, buffer_1
));
1477 uint32_t *buffer
[4] = { buffer_1
, buffer_2
, buffer_3
, buffer_4
};
1478 intptr_t virt
[4] = { sd
->ScratchArea
, sd
->ScratchArea
+ line_width
,
1479 sd
->ScratchArea
+ 2*line_width
, sd
->ScratchArea
+ 3*line_width
};
1481 HIDDT_PixelFormat
*srcpf
, *dstpf
;
1483 srcpf
= (HIDDT_PixelFormat
*)HIDD_Gfx_GetPixFmt(
1484 sd
->GMAObject
, msg
->pixFmt
);
1485 OOP_GetAttr(o
, aHidd_BitMap_PixFmt
, (APTR
)&dstpf
);
1487 /* Attach memory, if necessary */
1488 if (sd
->AttachedMemory
!= (intptr_t)buffer_1
|| sd
->AttachedSize
!= 4 * line_width
)
1490 G45_AttachCacheableMemory(sd
, (intptr_t)buffer_1
, sd
->ScratchArea
, 4 * line_width
);
1491 sd
->AttachedMemory
= (intptr_t)buffer_1
;
1492 sd
->AttachedSize
= 4 * line_width
;
1495 /* Both buffers are not busy */
1496 writel(1, &sd
->HardwareStatusPage
[17]);
1497 writel(1, &sd
->HardwareStatusPage
[18]);
1498 writel(1, &sd
->HardwareStatusPage
[19]);
1499 writel(1, &sd
->HardwareStatusPage
[20]);
1501 for (y
=0; y
< height
; y
++)
1503 const uint8_t current
= y
& 3;
1504 uint32_t *dst
= buffer
[current
];
1507 /* Wait until dst buffer is ready */
1508 while(readl(&sd
->HardwareStatusPage
[17 + current
]) == 0);
1511 HIDD_BM_ConvertPixels(o
, &_src
, srcpf
,
1512 msg
->modulo
, (APTR
*)&dst
, dstpf
,
1513 msg
->modulo
, msg
->width
, 1, NULL
);
1515 /* Mark buffer as busy */
1516 writel(0, &sd
->HardwareStatusPage
[17 + current
]);
1518 /* Prepare the Blit command */
1519 uint32_t br00
, br13
, br14
, br09
, br11
, br12
;
1521 br00
= (2 << 29) | (0x43 << 22) | (4);
1524 br13
= bm
->pitch
| ROP3_S
;
1527 br14
= (msg
->width
* bm
->bpp
) | (1) << 16;
1528 br09
= bm
->framebuffer
+ bm
->pitch
* (msg
->y
+ y
) + bm
->bpp
* msg
->x
;
1529 br11
= msg
->width
* bm
->bpp
;
1530 br12
= virt
[current
];
1541 OUT_RING((4 << 23));
1544 OUT_RING((0x21 << 23) | 1);
1545 OUT_RING((17 + current
) << 2);
1552 * Right now the buffer is busy. The commands will flush buffer and set the proper flag (17+current) back to 1.
1553 * During that time it is fully safe to advance the loop and work on another buffer with CPU.
1558 /* Wait until both buffer are ready */
1559 while(readl(&sd
->HardwareStatusPage
[17]) == 0);
1560 while(readl(&sd
->HardwareStatusPage
[18]) == 0);
1561 while(readl(&sd
->HardwareStatusPage
[19]) == 0);
1562 while(readl(&sd
->HardwareStatusPage
[20]) == 0);
1566 FreeVecPooled(sd
->MemPool
, pages
);
1569 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1572 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1574 } /* switch(msg->pixFmt) */
1580 VOID
METHOD(GMABM
, Hidd_BitMap
, PutImageLUT
)
1582 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1588 /* Get image width aligned to 4K page boundary */
1589 uint32_t line_width
= (msg
->width
* bm
->bpp
+ 4095) & ~4095;
1590 void *pages
= AllocVecPooled(sd
->MemPool
, line_width
* 3);
1591 HIDDT_Pixel
*colmap
= msg
->pixlut
->pixels
;
1597 if (bm
->bpp
== 4 && CanAccelerateBlits(sd
->ProductID
))
1599 /* Get two buffers in different GTT regions and _surely_ in different CPU cache lines */
1600 uint32_t *buffer_1
= (uint32_t *)(((intptr_t)pages
+ 4095) & ~4095);
1601 uint32_t *buffer_2
= &buffer_1
[line_width
/ 4];
1603 const uint32_t height
= msg
->height
;
1604 uint8_t *src
= msg
->pixels
;
1605 uint32_t x_add
= msg
->modulo
;
1607 D(bug("[GMA] PutImageLUT(%d, %d) with buffers at %p\n", msg
->width
, msg
->height
, buffer_1
));
1609 uint32_t *buffer
[2] = { buffer_1
, buffer_2
};
1610 intptr_t virt
[2] = { sd
->ScratchArea
, sd
->ScratchArea
+ line_width
};
1612 /* Attach memory, if necessary */
1613 if (sd
->AttachedMemory
!= (intptr_t)buffer_1
|| sd
->AttachedSize
!= 2 * line_width
)
1615 G45_AttachCacheableMemory(sd
, (intptr_t)buffer_1
, sd
->ScratchArea
, 2 * line_width
);
1616 sd
->AttachedMemory
= (intptr_t)buffer_1
;
1617 sd
->AttachedSize
= 2 * line_width
;
1620 /* Both buffers are not busy */
1621 writel(1, &sd
->HardwareStatusPage
[17]);
1622 writel(1, &sd
->HardwareStatusPage
[18]);
1624 for (y
=0; y
< height
; y
++)
1626 const uint8_t current
= y
& 1;
1627 uint32_t *dst
= buffer
[current
];
1629 uint8_t *line
= (uint8_t *)src
;
1630 const uint32_t width
= msg
->width
;
1632 /* Wait until dst buffer is ready */
1633 while(readl(&sd
->HardwareStatusPage
[17 + current
]) == 0);
1636 for (x
=0; x
< width
; x
++)
1637 dst
[x
] = colmap
[*line
++];
1639 /* Mark buffer as busy */
1640 writel(0, &sd
->HardwareStatusPage
[17 + current
]);
1642 /* Prepare the Blit command */
1643 uint32_t br00
, br13
, br14
, br09
, br11
, br12
;
1645 br00
= (2 << 29) | (0x43 << 22) | (4);
1649 br13
= bm
->pitch
| ROP3_S
;
1652 else if (bm
->bpp
== 2)
1655 br14
= (msg
->width
* bm
->bpp
) | (1) << 16;
1656 br09
= bm
->framebuffer
+ bm
->pitch
* (msg
->y
+ y
) + bm
->bpp
* msg
->x
;
1657 br11
= msg
->width
* bm
->bpp
;
1658 br12
= virt
[current
];
1669 OUT_RING((4 << 23));
1672 OUT_RING((0x21 << 23) | 1);
1673 OUT_RING((17 + current
) << 2);
1680 * Right now the buffer is busy. The commands will flush buffer and set the proper flag (17+current) back to 1.
1681 * During that time it is fully safe to advance the loop and work on another buffer with CPU.
1686 /* Wait until both buffer are ready */
1687 while(readl(&sd
->HardwareStatusPage
[17]) == 0);
1688 while(readl(&sd
->HardwareStatusPage
[18]) == 0);
1691 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1695 FreeVecPooled(sd
->MemPool
, pages
);
1698 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1701 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1706 VOID
METHOD(GMABM
, Hidd_BitMap
, GetImage
)
1708 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1713 // bug("[GMA] GetImage(%d, %d, fmt %d)\n", msg->width, msg->height, msg->pixFmt);
1715 IPTR VideoData
= bm
->framebuffer
;
1723 if (bm
->bpp
== 4 && CanAccelerateBlits(sd
->ProductID
)
1724 && (msg
->pixFmt
== vHidd_StdPixFmt_Native
1725 || msg
->pixFmt
== vHidd_StdPixFmt_Native32
))
1727 UBYTE
*dst
= msg
->pixels
;
1728 ULONG x_add
= msg
->modulo
;
1729 UWORD height
= msg
->height
;
1732 x_add
= bm
->bpp
* msg
->width
;
1736 intptr_t length
= x_add
* height
;
1737 intptr_t phys
= ((intptr_t)dst
) & 0xfffff000;
1738 length
+= (intptr_t)dst
- phys
;
1740 length
= (length
+ 4095) & ~4095;
1742 if (length
<= 16*1024*1024)
1744 intptr_t virt
= sd
->ScratchArea
+ ((intptr_t)dst
- phys
);
1747 D(bug("[GMA] GetImage(%d, %d) with buffer at %p\n", msg
->width
, msg
->height
, phys
));
1749 if (sd
->AttachedMemory
!= phys
|| sd
->AttachedSize
!= length
)
1751 G45_AttachCacheableMemory(sd
, phys
, sd
->ScratchArea
, length
);
1752 sd
->AttachedMemory
= phys
;
1753 sd
->AttachedSize
= length
;
1756 writel(0, &sd
->HardwareStatusPage
[16]);
1758 uint32_t br00
, br13
, br14
, br09
, br11
, br12
;
1760 br00
= (2 << 29) | (0x43 << 22) | (4);
1764 br13
= x_add
| ROP3_S
;
1767 else if (bm
->bpp
== 2)
1770 br14
= (x_add
) | (msg
->height
<< 16);
1773 br12
= bm
->framebuffer
+ bm
->pitch
* msg
->y
+ bm
->bpp
* msg
->x
;
1775 D(bug("[GMA] %08x %08x %08x %08x %08x %08x\n", br00
, br13
, br14
, br09
, br11
, br12
));
1786 OUT_RING((4 << 23));
1789 OUT_RING((0x21 << 23) | 1);
1799 /* Wait until HW is ready with blit and flush */
1800 while(readl(&sd
->HardwareStatusPage
[16]) == 0);
1804 VideoData
+= (IPTR
)sd
->Card
.Framebuffer
;
1811 case vHidd_StdPixFmt_Native
:
1816 struct pHidd_BitMap_CopyMemBox8 __m
= {
1817 sd
->mid_CopyMemBox8
,
1830 OOP_DoMethod(o
, (OOP_Msg
)m
);
1836 struct pHidd_BitMap_CopyMemBox16 __m
= {
1837 sd
->mid_CopyMemBox16
,
1850 OOP_DoMethod(o
, (OOP_Msg
)m
);
1855 // D(bug("[GMA] Native GetImage(%d, %d)\n", msg->width, msg->height));
1857 struct pHidd_BitMap_CopyMemBox32 __m
= {
1858 sd
->mid_CopyMemBox32
,
1871 OOP_DoMethod(o
, (OOP_Msg
)m
);
1875 } /* switch(data->bytesperpix) */
1878 case vHidd_StdPixFmt_Native32
:
1883 struct pHidd_BitMap_GetMem32Image8 __m
= {
1884 sd
->mid_GetMem32Image8
,
1895 OOP_DoMethod(o
, (OOP_Msg
)m
);
1901 struct pHidd_BitMap_GetMem32Image16 __m
= {
1902 sd
->mid_GetMem32Image16
,
1913 OOP_DoMethod(o
, (OOP_Msg
)m
);
1919 struct pHidd_BitMap_CopyMemBox32 __m
= {
1920 sd
->mid_CopyMemBox32
,
1933 OOP_DoMethod(o
, (OOP_Msg
)m
);
1937 } /* switch(data->bytesperpix) */
1941 OOP_DoSuperMethod(cl
, o
, (OOP_Msg
)msg
);
1944 } /* switch(msg->pixFmt) */
1953 VOID
METHOD(GMABM
, Hidd_BitMap
, PutTemplate
)
1955 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
1957 D(bug("[GMA] NO-ACCEL: BitMap::PutTemplate\n"));
1961 IPTR VideoData
= bm
->framebuffer
;
1965 VideoData
+= (IPTR
)sd
->Card
.Framebuffer
;
1970 // if (sd->Card.Busy)
1973 //#warning TODO: NVSync(sd)
1974 // RADEONWaitForIdleMMIO(sd);
1985 struct pHidd_BitMap_PutMemTemplate8 __m
= {
1986 sd
->mid_PutMemTemplate8
,
2000 OOP_DoMethod(o
, (OOP_Msg
)m
);
2006 struct pHidd_BitMap_PutMemTemplate16 __m
= {
2007 sd
->mid_PutMemTemplate16
,
2021 OOP_DoMethod(o
, (OOP_Msg
)m
);
2027 struct pHidd_BitMap_PutMemTemplate32 __m
= {
2028 sd
->mid_PutMemTemplate32
,
2042 OOP_DoMethod(o
, (OOP_Msg
)m
);
2045 } /* switch(bm->bpp) */
2050 VOID
METHOD(GMABM
, Hidd_BitMap
, PutPattern
)
2052 GMABitMap_t
*bm
= OOP_INST_DATA(cl
, o
);
2054 D(bug("[GMA] NO-ACCEL: BitMap::PutPattern\n"));
2058 IPTR VideoData
= bm
->framebuffer
;
2062 VideoData
+= (IPTR
)sd
->Card
.Framebuffer
;
2067 // if (sd->Card.Busy)
2070 //#warning TODO: NVSync(sd)
2071 // RADEONWaitForIdleMMIO(sd);
2082 struct pHidd_BitMap_PutMemPattern8 __m
= {
2083 sd
->mid_PutMemPattern8
,
2103 OOP_DoMethod(o
, (OOP_Msg
)m
);
2109 struct pHidd_BitMap_PutMemPattern16 __m
= {
2110 sd
->mid_PutMemPattern16
,
2130 OOP_DoMethod(o
, (OOP_Msg
)m
);
2136 struct pHidd_BitMap_PutMemPattern32 __m
= {
2137 sd
->mid_PutMemPattern32
,
2157 OOP_DoMethod(o
, (OOP_Msg
)m
);
2160 } /* switch(bm->bpp) */
2165 VOID
METHOD(GMABM
, Hidd_BitMap
, UpdateRect
)
2167 GMABitMap_t
* bmdata
= OOP_INST_DATA(cl
, o
);
2168 D(bug("[GMA]BitMap::UpdateRect %d,%d-%d,%d o=%p\n",msg
->x
,msg
->y
,msg
->width
,msg
->height
,o
));
2169 if (bmdata
->displayable
)
2171 struct pHidd_Compositing_BitMapRectChanged brcmsg
=
2173 mID
: SD(cl
)->mid_BitMapRectChanged
,
2178 height
: msg
->height
2180 OOP_DoMethod(bmdata
->compositing
, (OOP_Msg
)&brcmsg
);
2185 static const struct OOP_MethodDescr GMABM_Root_descr
[] =
2187 {(OOP_MethodFunc
)GMABM__Root__New
, moRoot_New
},
2188 {(OOP_MethodFunc
)GMABM__Root__Dispose
, moRoot_Dispose
},
2189 {(OOP_MethodFunc
)GMABM__Root__Get
, moRoot_Get
},
2190 {(OOP_MethodFunc
)GMABM__Root__Set
, moRoot_Set
},
2193 #define NUM_GMABM_Root_METHODS 4
2195 static const struct OOP_MethodDescr GMABM_Hidd_BitMap_descr
[] =
2197 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutPixel
, moHidd_BitMap_PutPixel
},
2198 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__GetPixel
, moHidd_BitMap_GetPixel
},
2199 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__DrawPixel
, moHidd_BitMap_DrawPixel
},
2200 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__DrawLine
, moHidd_BitMap_DrawLine
},
2201 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__DrawEllipse
, moHidd_BitMap_DrawEllipse
},
2202 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__FillRect
, moHidd_BitMap_FillRect
},
2203 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__BytesPerLine
, moHidd_BitMap_BytesPerLine
},
2204 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__ObtainDirectAccess
, moHidd_BitMap_ObtainDirectAccess
},
2205 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__ReleaseDirectAccess
, moHidd_BitMap_ReleaseDirectAccess
},
2206 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutImage
, moHidd_BitMap_PutImage
},
2207 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutImageLUT
, moHidd_BitMap_PutImageLUT
},
2208 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutAlphaImage
, moHidd_BitMap_PutAlphaImage
},
2209 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__GetImage
, moHidd_BitMap_GetImage
},
2210 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutTemplate
, moHidd_BitMap_PutTemplate
},
2211 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__PutPattern
, moHidd_BitMap_PutPattern
},
2212 {(OOP_MethodFunc
)GMABM__Hidd_BitMap__UpdateRect
, moHidd_BitMap_UpdateRect
},
2215 #define NUM_GMABM_Hidd_BitMap_METHODS 16
2217 const struct OOP_InterfaceDescr GMABM_ifdescr
[] =
2219 {GMABM_Root_descr
, IID_Root
, NUM_GMABM_Root_METHODS
},
2220 {GMABM_Hidd_BitMap_descr
, IID_Hidd_BitMap
, NUM_GMABM_Hidd_BitMap_METHODS
},