2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
9 #include <aros/debug.h>
10 #include <hidd/graphics.h>
11 #include <proto/cybergraphics.h>
13 #include "cybergraphics_intern.h"
14 #include "gfxfuncsupport.h"
18 OOP_Object
*srcbm_obj
;
22 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
23 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
24 struct GfxBase
*GfxBase
);
26 /* Terrifying bad hack to work around a GCC issue with AROS_LH10 macros.
28 * On gcc v4 on m68k, we get a register spill during certain optimization
29 * levels, due to the AROS_LH10() macro using so many registers.
31 * This 'hack' thunks the register call to a stack call, so that the gcc
32 * optimizer has more registers to play with. It must have global scope
33 * (not 'static') so that it doesn't fold into the regcall routine.
35 * On non-regcall systems, this will, at worst, convert to a 'JMP internal_ScalePixelArray' with no stack manipulation.
37 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
, UWORD SrcMod
, struct RastPort
*RastPort
, UWORD DestX
, UWORD DestY
, UWORD DestW
, UWORD DestH
, UBYTE SrcFormat
, struct Library
*CyberGfxBase
);
39 /*****************************************************************************
42 #include <proto/cybergraphics.h>
44 AROS_LH10(LONG
, ScalePixelArray
,
47 AROS_LHA(APTR
, srcRect
, A0
),
48 AROS_LHA(UWORD
, SrcW
, D0
),
49 AROS_LHA(UWORD
, SrcH
, D1
),
50 AROS_LHA(UWORD
, SrcMod
, D2
),
51 AROS_LHA(struct RastPort
*, RastPort
, A1
),
52 AROS_LHA(UWORD
, DestX
, D3
),
53 AROS_LHA(UWORD
, DestY
, D4
),
54 AROS_LHA(UWORD
, DestW
, D5
),
55 AROS_LHA(UWORD
, DestH
, D6
),
56 AROS_LHA(UBYTE
, SrcFormat
, D7
),
59 struct Library
*, CyberGfxBase
, 15, Cybergraphics
)
62 Fills all or part of a RastPort with a rectangular block of raw pixel
63 values. The source pixels are scaled to fit the destination area, i.e.
64 some pixels may be duplicated or dropped according to the need to
65 stretch or compress the source block.
68 srcRect - pointer to the pixel values.
69 SrcW, SrcH - width and height of the source rectangle (in pixels).
70 SrcMod - the number of bytes in each row of the source rectangle.
71 RastPort - the RastPort to write to.
72 DestX, DestY - top-lefthand corner of portion of destination RastPort
73 to write to (in pixels).
74 DestW, DestH - size of the destination rectangle (in pixels).
75 SrcFormat - the format of the source pixels. See WritePixelArray for
79 count - the number of pixels written to.
92 *****************************************************************************/
96 return internal_ScalePixelArray(srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
, DestX
, DestY
, DestW
, DestH
, SrcFormat
, CyberGfxBase
);
101 LONG
internal_ScalePixelArray(APTR srcRect
, UWORD SrcW
, UWORD SrcH
, UWORD SrcMod
, struct RastPort
*RastPort
, UWORD DestX
, UWORD DestY
, UWORD DestW
, UWORD DestH
, UBYTE SrcFormat
, struct Library
*CyberGfxBase
)
104 struct render_data data
;
106 OOP_Object
*gfx_hidd
, *tempbm_obj
, *tempbm2_obj
, *gc
;
107 struct BitScaleArgs scale_args
= {0};
108 struct TagItem bm_tags
[] =
110 {aHidd_BitMap_GfxHidd
, 0},
111 {aHidd_BitMap_Width
, SrcW
},
112 {aHidd_BitMap_Height
, SrcH
},
113 {aHidd_BitMap_StdPixFmt
, 0},
116 struct TagItem gc_tags
[] =
118 {aHidd_GC_DrawMode
, vHidd_GC_DrawMode_Copy
},
122 D(bug("ScalePixelArray(%p, %d, %d, %d, %p, %d, %d, %d, %d, %d)\n",
123 srcRect
, SrcW
, SrcH
, SrcMod
, RastPort
, DestX
, DestY
, DestW
, DestH
,
126 if (SrcW
== 0 || SrcH
== 0 || DestW
== 0 || DestH
== 0)
129 /* This is cybergraphx. We only work wih HIDD bitmaps */
131 if (!IS_HIDD_BM(RastPort
->BitMap
))
133 D(bug("!!!!! Trying to use CGFX call on non-hidd bitmap in ScalePixelArray() !!!\n"));
137 /* Get graphics HIDD and a graphics context */
139 OOP_GetAttr(HIDD_BM_OBJ(RastPort
->BitMap
), aHidd_BitMap_GfxHidd
,
141 gc
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basegc
, gc_tags
);
144 /* Create two temporary bitmap objects: one the size of the source area
145 and another the size of the destination area */
147 bm_tags
[0].ti_Data
= (IPTR
)gfx_hidd
;
148 bm_tags
[3].ti_Data
= GetHIDDRectFmt(SrcFormat
, RastPort
, CyberGfxBase
);
149 tempbm_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
152 bm_tags
[1].ti_Data
= DestW
;
153 bm_tags
[2].ti_Data
= DestH
;
155 // FIXME: This doesn't work (X11 and VESA). Should it?
156 bm_tags
[3].ti_Tag
= aHidd_BitMap_Friend
;
157 bm_tags
[3].ti_Data
= (IPTR
)HIDD_BM_OBJ(RastPort
->BitMap
);
159 tempbm2_obj
= HIDD_Gfx_CreateObject(gfx_hidd
, GetCGFXBase(CyberGfxBase
)->basebm
, bm_tags
);
162 /* Copy the source array to its temporary bitmap object */
164 HIDD_BM_PutImage(tempbm_obj
, gc
, srcRect
, SrcMod
, 0, 0, SrcW
, SrcH
,
165 vHidd_StdPixFmt_Native
);
167 /* Scale temporary source bitmap on to temporary destination bitmap */
169 scale_args
.bsa_SrcWidth
= SrcW
;
170 scale_args
.bsa_SrcHeight
= SrcH
;
171 scale_args
.bsa_DestWidth
= DestW
;
172 scale_args
.bsa_DestHeight
= DestH
;
173 HIDD_BM_BitMapScale(tempbm2_obj
, tempbm_obj
, tempbm2_obj
, &scale_args
,
176 /* Render temporary destination bitmap to destination bitmap */
178 data
.srcbm_obj
= tempbm2_obj
;
179 data
.gfx_hidd
= gfx_hidd
;
182 rr
.MaxX
= DestX
+ DestW
- 1;
183 rr
.MaxY
= DestY
+ DestH
- 1;
184 result
= DoRenderFunc(RastPort
, NULL
, &rr
, RenderHook
, &data
, TRUE
);
186 // Discard temporary resources ...
188 OOP_DisposeObject(tempbm2_obj
);
190 OOP_DisposeObject(tempbm_obj
);
192 OOP_DisposeObject(gc
);
196 } /* ScalePixelArray */
198 static ULONG
RenderHook(struct render_data
*data
, LONG srcx
, LONG srcy
,
199 OOP_Object
*dstbm_obj
, OOP_Object
*dst_gc
, struct Rectangle
*rect
,
200 struct GfxBase
*GfxBase
)
202 ULONG width
= rect
->MaxX
- rect
->MinX
+ 1;
203 ULONG height
= rect
->MaxY
- rect
->MinY
+ 1;
205 HIDD_Gfx_CopyBox(data
->gfx_hidd
, data
->srcbm_obj
, srcx
, srcy
, dstbm_obj
,
206 rect
->MinX
, rect
->MinY
, width
, height
, dst_gc
);
208 return width
* height
;