2 * Select a driver to call for operations between struct BitMap (source) and OOP_Object (destination).
3 * Used by BltBitMapRastPort() and BltMaskBitMapRastPort().
6 * 1. If one of drivers is fakegfx.hidd, we must use it in order
7 * to de-masquerade fakefb objects.
8 * 2. If one of drivers is our default software bitmap driver,
9 * we use another one, which can be an accelerated video driver.
11 static inline OOP_Object
*SelectDriverObject(struct BitMap
*srcbm
, OOP_Object
*dstbm_obj
, struct GfxBase
*GfxBase
)
13 struct monitor_driverdata
*driver
= GET_BM_DRIVERDATA(srcbm
);
14 OOP_Object
*gfxhidd
= driver
->gfxhidd
;
15 OOP_Object
*dest_gfxhidd
;
17 OOP_GetAttr(dstbm_obj
, aHidd_BitMap_GfxHidd
, (IPTR
*)&dest_gfxhidd
);
19 if (driver
== (struct monitor_driverdata
*)CDD(GfxBase
))
22 * If source bitmap is generic software one, we select destination bitmap.
23 * It can be either fakegfx or accelerated hardware driver.
27 else if (OOP_OCLASS(dest_gfxhidd
) == CDD(GfxBase
)->fakegfxclass
)
30 * If destination bitmap is fakegfx bitmap, we use its driver.
31 * Source one might be not fakegfx.
38 * If both tests failed, we use source driver. We know that source it not a
39 * generic software driver, and destination is not fakegfx. So, source
40 * can be either fakegfx or hardware driver.
46 static inline OOP_Object
*GetDriverData(struct RastPort
*rp
, struct GfxBase
*GfxBase
)
49 * Here we do a little bit of hacky-wacky magic.
50 * As we all know, there is no common call for RastPort deinitialization.
51 * At the other hand, we need some way to represent a RastPort as GC object to our graphics drivers.
52 * Fortunately, RastPort has enough private space in it to embed a specially-made GC object.
54 * There are several restrictions in such approach:
55 * 1. We must never OOP_DisposeObject() this GC. It is not a real issue, because this object is assumed
56 * to be owned by graphics.library, and only it has rights to dispose it.
57 * 2. We can't use subclasses of this class. Since GC is just a data container, nobody needed to subclass
58 * it until and including now. I hope this won't ever become an issue. Additionally, with current
59 * graphics.library design, GC objects are freely passed accross different display drivers.
61 * Well, so, we need to build an OOP_Object of GC class without doing any allocations.
62 * Is it possible? Yes, it is. We need to know three facts in order to do this:
63 * 1. OOP_Object is actually a class pointer, *preceding* instance data structure.
64 * 2. GC's superclass is root class. So, its instance data has offset 0.
65 * 3. As i said above, size of the complete object perfectly fits inside RastPort's private area.
68 /* Take our instance data, this will be our object pointer. Having it as APTR gets rid of warnings */
72 * Now fill in attributes. We could perfectly use OOP_SetAttrs(), but why?
73 * It's our own object, let's go fast!
75 if (!(rp
->Flags
& RPF_NO_PENS
))
77 /* If PenMode is disabled, FG and BG are already set */
78 GC_FG(gc
) = rp
->BitMap
? BM_PIXEL(rp
->BitMap
, rp
->FgPen
& PEN_MASK
) : rp
->FgPen
;
79 GC_BG(gc
) = rp
->BitMap
? BM_PIXEL(rp
->BitMap
, rp
->BgPen
& PEN_MASK
) : rp
->BgPen
;
81 GC_DRMD(gc
) = vHidd_GC_DrawMode_Copy
;
85 /* Now set GC's DrawMode (effectively ROP) and color expansion (actually transparency) flags */
86 if (rp
->DrawMode
& JAM2
)
88 GC_COLEXP(gc
) = vHidd_GC_ColExp_Opaque
;
90 else if (rp
->DrawMode
& COMPLEMENT
)
92 GC_DRMD(gc
) = vHidd_GC_DrawMode_Invert
;
94 else if ((rp
->DrawMode
& (~INVERSVID
)) == JAM1
)
96 GC_COLEXP(gc
) = vHidd_GC_ColExp_Transparent
;
99 /* FIXME: Handle INVERSVID by swapping apen and bpen ? */
101 OOP_OCLASS(gc
) = CDD(GfxBase
)->gcClass
; /* Set class pointer */
102 return gc
; /* Our handmade object is ready to use! */