Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / libs / cgfx / scalepixelarray.c
blob1f1c747246929ccbc6cb78283b10a1b06b6f7042
1 /*
2 Copyright © 1995-2015, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: english
7 */
9 #include <aros/debug.h>
10 #include <hidd/graphics.h>
11 #include <proto/cybergraphics.h>
13 #include "cybergraphics_intern.h"
14 #include "gfxfuncsupport.h"
16 struct render_data
18 OOP_Object *srcbm_obj;
19 OOP_Object *gfx_hidd;
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 /*****************************************************************************
41 NAME */
42 #include <proto/cybergraphics.h>
44 AROS_LH10(LONG, ScalePixelArray,
46 /* SYNOPSIS */
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),
58 /* LOCATION */
59 struct Library *, CyberGfxBase, 15, Cybergraphics)
61 /* FUNCTION
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.
67 INPUTS
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
76 possible values.
78 RESULT
79 count - the number of pixels written to.
81 NOTES
83 EXAMPLE
85 BUGS
87 SEE ALSO
88 WritePixelArray()
90 INTERNALS
92 *****************************************************************************/
94 AROS_LIBFUNC_INIT
96 return internal_ScalePixelArray(srcRect, SrcW, SrcH, SrcMod, RastPort, DestX, DestY, DestW, DestH, SrcFormat, CyberGfxBase);
98 AROS_LIBFUNC_EXIT
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)
103 ULONG result = 0;
104 struct render_data data;
105 struct Rectangle rr;
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},
114 {TAG_END, 0}
116 struct TagItem gc_tags[] =
118 {aHidd_GC_DrawMode, vHidd_GC_DrawMode_Copy},
119 {TAG_DONE, 0UL}
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,
124 SrcFormat));
126 if (SrcW == 0 || SrcH == 0 || DestW == 0 || DestH == 0)
127 return 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"));
134 return 0;
137 /* Get graphics HIDD and a graphics context */
139 OOP_GetAttr(HIDD_BM_OBJ(RastPort->BitMap), aHidd_BitMap_GfxHidd,
140 (IPTR *)&gfx_hidd);
141 gc = HIDD_Gfx_CreateObject(gfx_hidd, GetCGFXBase(CyberGfxBase)->basegc, gc_tags);
142 if (gc)
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);
150 if (tempbm_obj)
152 bm_tags[1].ti_Data = DestW;
153 bm_tags[2].ti_Data = DestH;
154 #if 0
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);
158 #endif
159 tempbm2_obj = HIDD_Gfx_CreateObject(gfx_hidd, GetCGFXBase(CyberGfxBase)->basebm, bm_tags);
160 if (tempbm2_obj)
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,
174 gc);
176 /* Render temporary destination bitmap to destination bitmap */
178 data.srcbm_obj = tempbm2_obj;
179 data.gfx_hidd = gfx_hidd;
180 rr.MinX = DestX;
181 rr.MinY = DestY;
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);
195 return result;
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;