Hint added.
[AROS.git] / workbench / hidds / nouveau / nouveaubitmapclass.c
blob42b167f11e8ece111d7e8ebc1d648372c83f7b49
1 /*
2 Copyright © 2010-2015, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include "nouveau_intern.h"
8 #define DEBUG 0
9 #include <aros/debug.h>
10 #include <proto/oop.h>
11 #include <proto/utility.h>
13 #include "arosdrmmode.h"
15 #undef HiddBitMapAttrBase
16 #undef HiddPixFmtAttrBase
17 #undef HiddBitMapNouveauAttrBase
19 #define HiddBitMapAttrBase (SD(cl)->bitMapAttrBase)
20 #define HiddPixFmtAttrBase (SD(cl)->pixFmtAttrBase)
21 #define HiddBitMapNouveauAttrBase (SD(cl)->bitMapNouveauAttrBase)
23 #define GART_TRANSFER_ALLOWED(width, height) ((((width) * (height)) >= (32 * 32)) && (carddata->GART))
25 VOID HIDDNouveauSetOffsets(OOP_Object * bm, LONG newxoffset, LONG newyoffset)
27 OOP_Class * cl = OOP_OCLASS(bm);
28 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, bm);
29 bmdata->xoffset = newxoffset;
30 bmdata->yoffset = newyoffset;
33 /* PUBLIC METHODS */
34 OOP_Object * METHOD(NouveauBitMap, Root, New)
36 IPTR width, height, depth, displayable, bytesperpixel;
37 OOP_Object * pf;
38 struct HIDDNouveauBitMapData * bmdata = NULL;
39 HIDDT_StdPixFmt stdfmt = vHidd_StdPixFmt_Unknown;
40 struct CardData * carddata = &(SD(cl)->carddata);
42 o = (OOP_Object *)OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
44 if (!o)
45 goto exit_fail;
47 bmdata = OOP_INST_DATA(cl, o);
49 /* Initialize default values */
50 bmdata->fbid = 0;
51 bmdata->xoffset = 0;
52 bmdata->yoffset = 0;
53 bmdata->bo = NULL;
55 OOP_GetAttr(o, aHidd_BitMap_Width, &width);
56 OOP_GetAttr(o, aHidd_BitMap_Height, &height);
57 OOP_GetAttr(o, aHidd_BitMap_PixFmt, (APTR)&pf);
58 OOP_GetAttr(o, aHidd_BitMap_Displayable, &displayable);
59 OOP_GetAttr(pf, aHidd_PixFmt_StdPixFmt, &stdfmt);
60 OOP_GetAttr(pf, aHidd_PixFmt_BytesPerPixel, &bytesperpixel);
61 OOP_GetAttr(pf, aHidd_PixFmt_Depth, &depth);
63 D(bug("[Nouveau] BitMap New: %d x %d x %d\n", width, height, depth));
65 /* Check if requested format is one of the supported ones */
66 if ((stdfmt != vHidd_StdPixFmt_BGR032) && (stdfmt != vHidd_StdPixFmt_RGB16_LE))
67 goto exit_fail;
69 /* Check if requested depth is a supported one */
70 if (depth < 16)
71 goto exit_fail;
73 /* Check if requested byted per pixel is a supported one */
74 if ((bytesperpixel != 2) && (bytesperpixel != 4))
75 goto exit_fail;
77 /* Initialize properties */
78 bmdata->width = width;
79 bmdata->height = height;
80 bmdata->depth = depth;
81 bmdata->bytesperpixel = bytesperpixel;
82 bmdata->pitch = bmdata->width * bmdata->bytesperpixel;
83 if (carddata->architecture >= NV_ARCH_50)
84 bmdata->pitch = (bmdata->pitch + 255) & ~255;
85 else
86 bmdata->pitch = (bmdata->pitch + 63) & ~63;
88 if (displayable) bmdata->displayable = TRUE; else bmdata->displayable = FALSE;
89 InitSemaphore(&bmdata->semaphore);
91 /* Creation of buffer object */
92 nouveau_bo_new(SD(cl)->carddata.dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_MAP, 0,
93 bmdata->pitch * bmdata->height,
94 &bmdata->bo);
95 if (bmdata->bo == NULL)
96 goto exit_fail;
98 bmdata->compositor = (OOP_Object *)GetTagData(aHidd_BitMap_Nouveau_CompositorHidd, 0, msg->attrList);
99 if (bmdata->compositor == NULL)
100 goto exit_fail;
102 return o;
104 exit_fail:
106 bug("[Nouveau]: Failed to create bitmap %dx%d %d %d\n", width, height, depth, stdfmt);
108 if (o)
110 OOP_MethodID disp_mid = OOP_GetMethodID(IID_Root, moRoot_Dispose);
111 OOP_CoerceMethod(cl, o, (OOP_Msg) &disp_mid);
114 return NULL;
117 VOID NouveauBitMap__Root__Dispose(OOP_Class *cl, OOP_Object *o, OOP_Msg msg)
119 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
121 D(bug("[Nouveau] Dispose %x\n", o));
123 /* Unregister from framebuffer if needed */
124 if (bmdata->fbid != 0)
126 struct nouveau_device_priv *nvdev = nouveau_device(SD(cl)->carddata.dev);
127 drmModeRmFB(nvdev->fd, bmdata->fbid);
128 bmdata->fbid = 0;
131 if (bmdata->bo)
133 UNMAP_BUFFER
134 nouveau_bo_ref(NULL, &bmdata->bo); /* Release reference */
137 OOP_DoSuperMethod(cl, o, msg);
140 VOID METHOD(NouveauBitMap, Root, Get)
142 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
143 ULONG idx;
145 if (IS_BITMAP_ATTR(msg->attrID, idx))
147 switch (idx)
149 case aoHidd_BitMap_LeftEdge:
150 *msg->storage = bmdata->xoffset;
151 return;
152 case aoHidd_BitMap_TopEdge:
153 *msg->storage = bmdata->yoffset;
154 return;
158 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
161 VOID METHOD(NouveauBitMap, Root, Set)
163 struct TagItem *tag, *tstate;
164 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
165 ULONG idx;
166 LONG newxoffset = bmdata->xoffset;
167 LONG newyoffset = bmdata->yoffset;
169 tstate = msg->attrList;
170 while((tag = NextTagItem(&tstate)))
172 if(IS_BITMAP_ATTR(tag->ti_Tag, idx))
174 switch(idx)
176 case aoHidd_BitMap_LeftEdge:
177 newxoffset = tag->ti_Data;
178 break;
179 case aoHidd_BitMap_TopEdge:
180 newyoffset = tag->ti_Data;
181 break;
186 if ((newxoffset != bmdata->xoffset) || (newyoffset != bmdata->yoffset))
188 /* If there was a change requested, validate it */
189 struct pHidd_Compositor_ValidateBitMapPositionChange vbpcmsg =
191 mID : SD(cl)->mid_ValidateBitMapPositionChange,
192 bm : o,
193 newxoffset : &newxoffset,
194 newyoffset : &newyoffset
197 OOP_DoMethod(bmdata->compositor, (OOP_Msg)&vbpcmsg);
199 if ((newxoffset != bmdata->xoffset) || (newyoffset != bmdata->yoffset))
201 /* If change passed validation, execute it */
202 struct pHidd_Compositor_BitMapPositionChanged bpcmsg =
204 mID : SD(cl)->mid_BitMapPositionChanged,
205 bm : o
208 HIDDNouveauSetOffsets(o, newxoffset, newyoffset);
210 OOP_DoMethod(bmdata->compositor, (OOP_Msg)&bpcmsg);
214 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
217 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutPixel)
219 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
220 IPTR addr = (msg->x * bmdata->bytesperpixel) + (bmdata->pitch * msg->y);
222 /* FIXME "Optimistics" synchronization (yes, I know it's wrong) */
223 IPTR map = (IPTR)bmdata->bo->map;
225 /* If the current map was NULL, wait until bitmap lock is released.
226 When it happens, map the buffer */
227 if (map == (IPTR)NULL)
229 LOCK_BITMAP
230 MAP_BUFFER
231 addr += (IPTR)bmdata->bo->map;
233 else
234 addr += map;
236 switch(bmdata->bytesperpixel)
238 case(1):
239 /* Not supported */
240 break;
241 case(2):
242 writew(msg->pixel, (APTR)addr);
243 break;
244 case(4):
245 writel(msg->pixel, (APTR)addr);
246 break;
249 if (map == (IPTR)NULL)
250 UNLOCK_BITMAP
253 HIDDT_Pixel METHOD(NouveauBitMap, Hidd_BitMap, GetPixel)
255 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
256 IPTR addr = (msg->x * bmdata->bytesperpixel) + (bmdata->pitch * msg->y);
257 HIDDT_Pixel pixel = 0;
259 /* FIXME "Optimistics" synchronization (yes, I know it's wrong) */
260 IPTR map = (IPTR)bmdata->bo->map;
262 /* If the current map was NULL, wait until bitmap lock is released.
263 When it happens, map the buffer */
264 if (map == (IPTR)NULL)
266 LOCK_BITMAP
267 MAP_BUFFER
268 addr += (IPTR)bmdata->bo->map;
270 else
271 addr += map;
273 switch(bmdata->bytesperpixel)
275 case(1):
276 /* Not supported */
277 break;
278 case(2):
279 pixel = readw((APTR)addr);
280 break;
281 case(4):
282 pixel = readl((APTR)addr);
283 break;
286 if (map == (IPTR)NULL)
287 UNLOCK_BITMAP
289 return pixel;
292 VOID METHOD(NouveauBitMap, Hidd_BitMap, Clear)
294 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
295 struct CardData * carddata = &(SD(cl)->carddata);
296 BOOL ret = FALSE;
298 LOCK_BITMAP
299 UNMAP_BUFFER
301 switch(carddata->architecture)
303 case(NV_ARCH_03):
304 case(NV_ARCH_04):
305 case(NV_ARCH_10):
306 case(NV_ARCH_20):
307 case(NV_ARCH_30):
308 case(NV_ARCH_40):
309 ret = HIDDNouveauNV04FillSolidRect(carddata, bmdata,
310 0, 0, bmdata->width - 1, bmdata->height - 1, GC_DRMD(msg->gc), GC_BG(msg->gc));
311 break;
312 case(NV_ARCH_50):
313 ret = HIDDNouveauNV50FillSolidRect(carddata, bmdata,
314 0, 0, bmdata->width - 1, bmdata->height - 1, GC_DRMD(msg->gc), GC_BG(msg->gc));
315 break;
316 case(NV_ARCH_C0):
317 ret = HIDDNouveauNVC0FillSolidRect(carddata, bmdata,
318 0, 0, bmdata->width - 1, bmdata->height - 1, GC_DRMD(msg->gc), GC_BG(msg->gc));
319 break;
322 UNLOCK_BITMAP
324 if (ret)
325 return;
327 /* Fallback to default method */
328 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
331 /* There is no pHidd_BitMap_FillRect structure - it's the same as pHidd_BitMap_DrawRect */
332 #define pHidd_BitMap_FillRect pHidd_BitMap_DrawRect
334 VOID METHOD(NouveauBitMap, Hidd_BitMap, FillRect)
336 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
337 struct CardData * carddata = &(SD(cl)->carddata);
338 BOOL ret = FALSE;
340 LOCK_BITMAP
341 UNMAP_BUFFER
343 switch(carddata->architecture)
345 case(NV_ARCH_03):
346 case(NV_ARCH_04):
347 case(NV_ARCH_10):
348 case(NV_ARCH_20):
349 case(NV_ARCH_30):
350 case(NV_ARCH_40):
351 ret = HIDDNouveauNV04FillSolidRect(carddata, bmdata,
352 msg->minX, msg->minY, msg->maxX, msg->maxY, GC_DRMD(msg->gc), GC_FG(msg->gc));
353 break;
354 case(NV_ARCH_50):
355 ret = HIDDNouveauNV50FillSolidRect(carddata, bmdata,
356 msg->minX, msg->minY, msg->maxX, msg->maxY, GC_DRMD(msg->gc), GC_FG(msg->gc));
357 break;
358 case(NV_ARCH_C0):
359 ret = HIDDNouveauNVC0FillSolidRect(carddata, bmdata,
360 msg->minX, msg->minY, msg->maxX, msg->maxY, GC_DRMD(msg->gc), GC_FG(msg->gc));
361 break;
364 UNLOCK_BITMAP
366 if (ret)
367 return;
369 /* Fallback to default method */
370 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
373 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutImage)
375 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
376 struct CardData * carddata = &(SD(cl)->carddata);
378 LOCK_BITMAP
380 /* For larger transfers use GART */
381 if (GART_TRANSFER_ALLOWED(msg->width, msg->height))
383 BOOL result = FALSE;
385 /* RAM->CPU->GART GART->GPU->VRAM */
386 UNMAP_BUFFER
388 ObtainSemaphore(&carddata->gartsemaphore);
390 result = HiddNouveauNVAccelUploadM2MF(
391 msg->pixels, msg->modulo, msg->pixFmt,
392 msg->x, msg->y, msg->width, msg->height,
393 cl, o);
395 ReleaseSemaphore(&carddata->gartsemaphore);
397 if (result)
399 UNLOCK_BITMAP;
400 return;
404 /* Fallback */
406 /* RAM->CPU->VRAM */
408 APTR dstBuff = NULL;
410 MAP_BUFFER
412 /* Calculate destination buffer pointer */
413 dstBuff = (APTR)((IPTR)bmdata->bo->map + (msg->y * bmdata->pitch) + (msg->x * bmdata->bytesperpixel));
415 HiddNouveauWriteFromRAM(
416 msg->pixels, msg->modulo, msg->pixFmt,
417 dstBuff, bmdata->pitch,
418 msg->width, msg->height,
419 cl, o);
422 UNLOCK_BITMAP
425 VOID METHOD(NouveauBitMap, Hidd_BitMap, GetImage)
427 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
428 struct CardData * carddata = &(SD(cl)->carddata);
430 LOCK_BITMAP
432 /* For larger transfers use GART */
433 if (GART_TRANSFER_ALLOWED(msg->width, msg->height))
435 BOOL result = FALSE;
437 /* VRAM->CPU->GART GART->GPU->RAM */
438 UNMAP_BUFFER
440 ObtainSemaphore(&carddata->gartsemaphore);
442 result = HiddNouveauNVAccelDownloadM2MF(
443 msg->pixels, msg->modulo, msg->pixFmt,
444 msg->x, msg->y, msg->width, msg->height,
445 cl, o);
447 ReleaseSemaphore(&carddata->gartsemaphore);
449 if (result)
451 UNLOCK_BITMAP;
452 return;
456 /* Fallback */
458 /* VRAM->CPU->RAM */
460 APTR srcBuff = NULL;
462 MAP_BUFFER
464 /* Calculate source buffer pointer */
465 srcBuff = (APTR)((IPTR)bmdata->bo->map + (msg->y * bmdata->pitch) + (msg->x * bmdata->bytesperpixel));
467 HiddNouveauReadIntoRAM(
468 srcBuff, bmdata->pitch,
469 msg->pixels, msg->modulo, msg->pixFmt,
470 msg->width, msg->height,
471 cl, o);
474 UNLOCK_BITMAP
477 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutAlphaImage)
479 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
480 struct CardData * carddata = &(SD(cl)->carddata);
482 LOCK_BITMAP
484 /* Try hardware method NV10-NV40*/
485 if (
486 ((carddata->architecture >= NV_ARCH_10) && (carddata->architecture <= NV_ARCH_40))
488 && (bmdata->bytesperpixel > 1)
489 && (GART_TRANSFER_ALLOWED(msg->width, msg->height)))
491 BOOL result = FALSE;
493 /* RAM->CPU->GART GART->GPU->VRAM */
494 UNMAP_BUFFER
496 ObtainSemaphore(&carddata->gartsemaphore);
498 result = HiddNouveauAccelARGBUpload3D(
499 msg->pixels, msg->modulo,
500 msg->x, msg->y, msg->width, msg->height,
501 cl, o);
503 ReleaseSemaphore(&carddata->gartsemaphore);
505 if (result)
507 MAP_BUFFER; /* FIXME: This is needed to flush execution buffer, atrifact otherwise */
508 UNLOCK_BITMAP;
509 return;
513 /* Try optimization for NV50 */
514 if (
515 (carddata->architecture >= NV_ARCH_50)
517 && (bmdata->bytesperpixel > 1)
518 && (GART_TRANSFER_ALLOWED(msg->width, msg->height)))
520 /* Hardware method is not currently possible for NV50 as the implementation
521 relies on tiled bitmaps. AROS uses linear bitmaps for all card families.
522 The optimization in this case is to use base class implementation,
523 which does GetImage->Process->PutImage. Since all NV50 cards are
524 PCI-E based, the greatest limiting factor - VRAM->RAM download
525 speed - is not a problem (1.1 Gbps on my GF8300). This approach is
526 actually faster than "per-pixel" functions below by order of 10. */
528 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
529 UNLOCK_BITMAP;
530 return;
533 /* Fallback to software method */
534 switch(bmdata->bytesperpixel)
536 case 1:
537 /* Not supported */
538 break;
540 case 2:
542 MAP_BUFFER
544 HIDDNouveauBitMapPutAlphaImage16(bmdata, msg->pixels, msg->modulo, msg->x,
545 msg->y, msg->width, msg->height);
547 break;
549 case 4:
551 MAP_BUFFER
553 HIDDNouveauBitMapPutAlphaImage32(bmdata, msg->pixels, msg->modulo, msg->x,
554 msg->y, msg->width, msg->height);
556 break;
557 } /* switch(bmdata->bytesperpixel) */
559 UNLOCK_BITMAP
562 ULONG METHOD(NouveauBitMap, Hidd_BitMap, BytesPerLine)
564 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
566 return (bmdata->pitch);
569 BOOL METHOD(NouveauBitMap, Hidd_BitMap, ObtainDirectAccess)
571 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
573 LOCK_BITMAP
574 MAP_BUFFER
576 *msg->addressReturn = (UBYTE*)bmdata->bo->map;
577 *msg->widthReturn = bmdata->pitch / bmdata->bytesperpixel;
578 *msg->heightReturn = bmdata->height;
579 *msg->bankSizeReturn = *msg->memSizeReturn = bmdata->pitch * bmdata->height;
581 return TRUE;
584 VOID METHOD(NouveauBitMap, Hidd_BitMap, ReleaseDirectAccess)
586 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
588 UNLOCK_BITMAP
591 #define COMPLEMENT_JAM2_DECISION_BLOCK \
592 else if (GC_DRMD(msg->gc) == vHidd_GC_DrawMode_Invert) \
594 /* COMPLEMENT - read & write. Base method uses GetImage/PutImage. \
595 It is better to use it, if GetImage is fast(==PCIE) */ \
596 if (GART_TRANSFER_ALLOWED(msg->width, msg->height) && (carddata->IsPCIE)) \
598 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg); \
599 return; \
602 else \
604 /* JAM2 - only write. Base method uses PutImage. It is \
605 better to use it, if it is accelerated */ \
606 if (GART_TRANSFER_ALLOWED(msg->width, msg->height)) \
608 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg); \
609 return; \
614 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutAlphaTemplate)
616 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
617 struct CardData * carddata = &(SD(cl)->carddata);
619 /* Select acceleration method based on hardware and buffer size */
620 if (GC_COLEXP(msg->gc) == vHidd_GC_ColExp_Transparent)
622 /* JAM1 - read & write. Base method uses GetImage/PutImage.
623 Use 3D alpha blending where possible */
624 if (GART_TRANSFER_ALLOWED(msg->width, msg->height))
626 /* These cards support 3D alpha blending */
627 if ((carddata->architecture >= NV_ARCH_10) && (carddata->architecture <= NV_ARCH_40))
629 BOOL result = FALSE;
630 HIDDT_Color color;
631 LONG fg_red, fg_green, fg_blue;
633 HIDD_BM_UnmapPixel(o, GC_FG(msg->gc), &color);
635 fg_red = color.red >> 8;
636 fg_green = color.green >> 8;
637 fg_blue = color.blue >> 8;
639 LOCK_BITMAP
640 UNMAP_BUFFER
642 ObtainSemaphore(&carddata->gartsemaphore);
644 result = HiddNouveauAccelAPENUpload3D(msg->alpha, msg->invertalpha,
645 msg->modulo, (fg_red << 16) | (fg_green << 8) | fg_blue,
646 msg->x, msg->y, msg->width, msg->height, cl, o);
648 ReleaseSemaphore(&carddata->gartsemaphore);
649 MAP_BUFFER; /* FIXME: This is needed to flush execution buffer, atrifact otherwise */
650 UNLOCK_BITMAP
652 if (result) return;
655 /* These cards don't support 3D alpha blending (yet), but they are all
656 PCIE so GetImage is fast */
657 if (carddata->architecture >= NV_ARCH_50)
659 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
660 return;
664 COMPLEMENT_JAM2_DECISION_BLOCK
666 /* This is software fallback */
667 LOCK_BITMAP
668 MAP_BUFFER
670 switch(bmdata->bytesperpixel)
672 case 1:
673 /* Not supported */
674 break;
676 case 2:
678 HIDDNouveauBitMapPutAlphaTemplate16(bmdata, msg->gc, o, msg->invertalpha,
679 msg->alpha, msg->modulo, msg->x, msg->y, msg->width, msg->height);
681 break;
683 case 4:
685 HIDDNouveauBitMapPutAlphaTemplate32(bmdata, msg->gc, o, msg->invertalpha,
686 msg->alpha, msg->modulo, msg->x, msg->y, msg->width, msg->height);
688 break;
689 } /* switch(bmdata->bytesperpixel) */
691 UNLOCK_BITMAP
694 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutTemplate)
696 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
697 struct CardData * carddata = &(SD(cl)->carddata);
699 /* Select execution method based on hardware and buffer size */
700 if (GC_COLEXP(msg->gc) == vHidd_GC_ColExp_Transparent)
702 /* JAM1 - read & write. Base method uses GetImage/PutImage.
703 Use software fallback. It performs only limited writes and thus it
704 is faster than base method. */
706 COMPLEMENT_JAM2_DECISION_BLOCK
708 /* This is software fallback */
709 LOCK_BITMAP
710 MAP_BUFFER
712 switch(bmdata->bytesperpixel)
714 case 1:
715 /* Not supported */
716 break;
718 case 2:
720 struct pHidd_BitMap_PutMemTemplate16 __m =
722 SD(cl)->mid_PutMemTemplate16, msg->gc, msg->masktemplate, msg->modulo,
723 msg->srcx, bmdata->bo->map, bmdata->pitch, msg->x, msg->y,
724 msg->width, msg->height, msg->inverttemplate
725 }, *m = &__m;
726 OOP_DoMethod(o, (OOP_Msg)m);
728 break;
730 case 4:
732 struct pHidd_BitMap_PutMemTemplate32 __m =
734 SD(cl)->mid_PutMemTemplate32, msg->gc, msg->masktemplate, msg->modulo,
735 msg->srcx, bmdata->bo->map, bmdata->pitch, msg->x, msg->y,
736 msg->width, msg->height, msg->inverttemplate
737 }, *m = &__m;
738 OOP_DoMethod(o, (OOP_Msg)m);
740 break;
741 } /* switch(bmdata->bytesperpixel) */
743 UNLOCK_BITMAP
746 VOID METHOD(NouveauBitMap, Hidd_BitMap, PutPattern)
748 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
749 struct CardData * carddata = &(SD(cl)->carddata);
751 /* Select execution method based on hardware and buffer size */
752 if (GC_COLEXP(msg->gc) == vHidd_GC_ColExp_Transparent)
754 /* JAM1 - read & write. Base method uses GetImage/PutImage.
755 Use software fallback. It performs only limited writes and thus it
756 is faster than base method. */
758 COMPLEMENT_JAM2_DECISION_BLOCK
760 /* This is software fallback */
761 LOCK_BITMAP
762 MAP_BUFFER
764 switch(bmdata->bytesperpixel)
766 case 1:
767 /* Not supported */
768 break;
770 case 2:
772 struct pHidd_BitMap_PutMemPattern16 __m =
774 SD(cl)->mid_PutMemPattern16, msg->gc, msg->pattern, msg->patternsrcx,
775 msg->patternsrcy, msg->patternheight, msg->patterndepth, msg->patternlut,
776 msg->invertpattern, msg->mask, msg->maskmodulo, msg->masksrcx,
777 bmdata->bo->map, bmdata->pitch, msg->x, msg->y, msg->width, msg->height
778 }, *m = &__m;
779 OOP_DoMethod(o, (OOP_Msg)m);
781 break;
783 case 4:
785 struct pHidd_BitMap_PutMemPattern32 __m =
787 SD(cl)->mid_PutMemPattern32, msg->gc, msg->pattern, msg->patternsrcx,
788 msg->patternsrcy, msg->patternheight, msg->patterndepth, msg->patternlut,
789 msg->invertpattern, msg->mask, msg->maskmodulo, msg->masksrcx,
790 bmdata->bo->map, bmdata->pitch, msg->x,msg->y, msg->width,
791 msg->height
792 }, *m = &__m;
793 OOP_DoMethod(o, (OOP_Msg)m);
795 break;
796 } /* switch(bmdata->bytesperpixel) */
798 UNLOCK_BITMAP
801 VOID METHOD(NouveauBitMap, Hidd_BitMap, DrawLine)
803 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
805 LOCK_BITMAP
807 if ((GC_DRMD(msg->gc) == vHidd_GC_DrawMode_Copy) && (GC_COLMASK(msg->gc) == ~0))
809 MAP_BUFFER
811 HIDDNouveauBitMapDrawSolidLine(bmdata, msg->gc, msg->x1, msg->y1, msg->x2, msg->y2);
813 UNLOCK_BITMAP
815 return;
818 OOP_DoSuperMethod(cl, o, (OOP_Msg)msg);
820 UNLOCK_BITMAP
823 VOID METHOD(NouveauBitMap, Hidd_BitMap, UpdateRect)
825 struct HIDDNouveauBitMapData * bmdata = OOP_INST_DATA(cl, o);
827 if (bmdata->displayable)
829 struct pHidd_Compositor_BitMapRectChanged brcmsg =
831 mID : SD(cl)->mid_BitMapRectChanged,
832 bm : o,
833 x : msg->x,
834 y : msg->y,
835 width : msg->width,
836 height : msg->height
839 OOP_DoMethod(bmdata->compositor, (OOP_Msg)&brcmsg);