91 /* Set target surface type mask */ |
92 /* Set target surface type mask */ |
92 |
93 |
93 attribs[5].attrib = EGL_SURFACE_TYPE; |
94 attribs[5].attrib = EGL_SURFACE_TYPE; |
94 attribs[5].value = surfaceBits; |
95 attribs[5].value = surfaceBits; |
95 |
96 |
96 /* Try to get multisampling if requested */ |
97 |
97 |
98 if (bitmapHandle) { |
98 attribs[6].attrib = EGL_SAMPLE_BUFFERS; |
99 /* This attribute is matched only for pixmap targets */ |
99 attribs[7].attrib = EGL_SAMPLES; |
100 attribs[6].attrib = EGL_MATCH_NATIVE_PIXMAP; |
100 attribs[8].attrib = EGL_NONE; |
101 attribs[6].value = bitmapHandle; |
101 |
102 |
|
103 /* Try to get multisampling if requested */ |
|
104 |
|
105 attribs[7].attrib = EGL_SAMPLE_BUFFERS; |
|
106 attribs[8].attrib = EGL_SAMPLES; |
|
107 |
|
108 attribs[9].attrib = EGL_NONE; |
|
109 } else { |
|
110 /* Try to get multisampling if requested */ |
|
111 |
|
112 attribs[6].attrib = EGL_SAMPLE_BUFFERS; |
|
113 attribs[7].attrib = EGL_SAMPLES; |
|
114 |
|
115 attribs[8].attrib = EGL_NONE; |
|
116 } |
|
117 |
|
118 |
102 /* Try 4 samples if multisampling enabled, then 2, then 1 */ |
119 /* Try 4 samples if multisampling enabled, then 2, then 1 */ |
103 |
120 |
104 samples = (bufferBits & M3G_MULTISAMPLE_BUFFER_BIT) ? 4 : 1; |
121 samples = (bufferBits & M3G_MULTISAMPLE_BUFFER_BIT) ? 4 : 1; |
105 for ( ; samples > 0; samples >>= 1) { |
122 for ( ; samples > 0; samples >>= 1) { |
106 |
123 |
107 if (samples > 1) { |
124 if (bitmapHandle) { |
108 attribs[6].value = 1; |
125 if (samples > 1) { |
109 attribs[7].value = samples; |
126 attribs[7].value = 1; |
110 } |
127 attribs[8].value = samples; |
111 else { |
128 } |
112 attribs[6].value = EGL_FALSE; |
129 else { |
113 attribs[7].value = 0; |
130 attribs[7].value = EGL_FALSE; |
|
131 attribs[8].value = 0; |
|
132 } |
|
133 } else { |
|
134 if (samples > 1) { |
|
135 attribs[6].value = 1; |
|
136 attribs[7].value = samples; |
|
137 } |
|
138 else { |
|
139 attribs[6].value = EGL_FALSE; |
|
140 attribs[7].value = 0; |
|
141 } |
114 } |
142 } |
115 |
143 |
116 /* Get the first matching config; according to EGL sorting |
144 /* Get the first matching config; according to EGL sorting |
117 * rules, this should be an accelerated one if possible */ |
145 * rules, this should be an accelerated one if possible */ |
118 { |
146 { |
119 EGLConfig config; |
147 EGLConfig config; |
120 int numConfigs; |
148 int numConfigs; |
|
149 EGLint error; |
|
150 |
121 eglChooseConfig(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
151 eglChooseConfig(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
122 (const int *) attribs, |
152 (const int *) attribs, |
123 &config, 1, |
153 &config, 1, |
124 &numConfigs); |
154 &numConfigs); |
125 |
155 |
126 M3G_ASSERT(eglGetError() == EGL_SUCCESS); |
156 error = eglGetError(); |
|
157 if (error != EGL_SUCCESS) { |
|
158 M3G_LOG1(M3G_LOG_FATAL_ERRORS, "eglChooseConfig failed: %d\n", error); |
|
159 } |
|
160 |
|
161 |
|
162 M3G_ASSERT(error == EGL_SUCCESS); |
127 |
163 |
128 /* If we got a config, return that; otherwise, drop the |
164 /* If we got a config, return that; otherwise, drop the |
129 * number of multisampling samples and try again, or |
165 * number of multisampling samples and try again, or |
130 * return NULL for no config if we already have zero |
166 * return NULL for no config if we already have zero |
131 * samples */ |
167 * samples */ |
168 |
205 |
169 /*! |
206 /*! |
170 * \internal |
207 * \internal |
171 * \brief Creates a new EGL context |
208 * \brief Creates a new EGL context |
172 */ |
209 */ |
173 static EGLContext m3gCreateGLContext(M3Genum format, |
210 /*static EGLContext m3gCreateGLContext(M3Genum format, |
174 M3Gbitmask bufferBits, |
211 M3Gbitmask bufferBits, |
175 M3Gbitmask reqSurfaceBits, |
212 M3Gbitmask reqSurfaceBits, |
176 EGLContext share, |
213 EGLContext share, |
177 M3Gbitmask *outSurfaceBits) |
214 M3Gbitmask *outSurfaceBits) |
178 { |
215 { |
179 EGLContext ctx; |
216 EGLContext ctx; |
180 EGLConfig config; |
217 EGLConfig config; |
181 |
218 |
182 M3G_ASSERT((reqSurfaceBits & ~(EGL_PIXMAP_BIT|EGL_PBUFFER_BIT|EGL_WINDOW_BIT)) == 0); |
219 M3G_ASSERT((reqSurfaceBits & ~(EGL_PIXMAP_BIT|EGL_PBUFFER_BIT|EGL_WINDOW_BIT)) == 0); |
183 |
220 |
184 config = m3gQueryEGLConfig(format, bufferBits, reqSurfaceBits); |
221 config = m3gQueryEGLConfig(format, bufferBits, reqSurfaceBits, NULL); |
185 |
222 |
186 if (!config || !eglGetConfigAttrib(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
223 if (!config || !eglGetConfigAttrib(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
187 config, |
224 config, |
188 EGL_SURFACE_TYPE, |
225 EGL_SURFACE_TYPE, |
189 (EGLint *) outSurfaceBits)) { |
226 (EGLint *) outSurfaceBits)) { |
916 static void m3gUpdateBackBuffer(RenderContext *ctx) |
954 static void m3gUpdateBackBuffer(RenderContext *ctx) |
917 { |
955 { |
918 if (ctx->target.type == SURFACE_IMAGE) { |
956 if (ctx->target.type == SURFACE_IMAGE) { |
919 m3gDrawFrameBufferImage(ctx, (Image *) ctx->target.handle); |
957 m3gDrawFrameBufferImage(ctx, (Image *) ctx->target.handle); |
920 } |
958 } |
921 else if (ctx->target.type == SURFACE_BITMAP) { |
959 else if (ctx->target.type == SURFACE_BITMAP || ctx->target.type == SURFACE_MEMORY) { |
922 |
960 |
923 M3Gubyte *src; |
961 M3Gubyte *src; |
924 M3Gsizei stride; |
962 M3Gsizei stride; |
925 |
963 |
926 /* Obtain a pointer to the native bitmap and copy the data to |
964 M3Gint clipWidth = ctx->clip.x1 - ctx->clip.x0; |
927 * the backbuffer from there */ |
965 M3Gint clipHeight = ctx->clip.y1 - ctx->clip.y0; |
928 |
966 M3Gint srcOffset; |
929 if (m3gglLockNativeBitmap((M3GNativeBitmap) ctx->target.handle, |
967 |
930 &src, &stride)) { |
968 if (ctx->target.type == SURFACE_BITMAP) { |
931 |
969 /* Obtain a pointer to the native bitmap and copy the data to |
932 M3Gint clipWidth = ctx->clip.x1 - ctx->clip.x0; |
970 * the backbuffer from there */ |
933 M3Gint clipHeight = ctx->clip.y1 - ctx->clip.y0; |
971 if (!m3gglLockNativeBitmap((M3GNativeBitmap) ctx->target.handle, |
934 M3Gint srcOffset = |
972 &src, &stride)) { |
935 (ctx->target.height - ctx->clip.y1) * stride |
973 /* No dice! There's no way that we know of to copy the |
936 + ctx->clip.x0 * m3gBytesPerPixel(ctx->target.format); |
974 * data between the buffers */ |
937 |
975 M3G_ASSERT(M3G_FALSE); |
938 m3gBlitFrameBufferPixels( |
976 } |
939 ctx, |
977 } else { |
940 ctx->clip.x0, ctx->clip.y0, |
978 /* Memory target */ |
941 clipWidth, clipHeight, |
979 src = ctx->target.pixels; |
942 ctx->target.format, |
980 stride = ctx->target.stride; |
943 stride, |
981 } |
944 src + srcOffset); |
982 |
945 |
983 srcOffset = |
|
984 (ctx->target.height - ctx->clip.y1) * stride |
|
985 + ctx->clip.x0 * m3gBytesPerPixel(ctx->target.format); |
|
986 |
|
987 m3gBlitFrameBufferPixels( |
|
988 ctx, |
|
989 ctx->clip.x0, ctx->clip.y0, |
|
990 clipWidth, clipHeight, |
|
991 ctx->target.format, |
|
992 stride, |
|
993 src + srcOffset); |
|
994 |
|
995 if (ctx->target.type == SURFACE_BITMAP) { |
946 m3gglReleaseNativeBitmap((M3GNativeBitmap) ctx->target.handle); |
996 m3gglReleaseNativeBitmap((M3GNativeBitmap) ctx->target.handle); |
947 } |
|
948 else { |
|
949 /* No dice! There's no way that we know of to copy the |
|
950 * data between the buffers */ |
|
951 M3G_ASSERT(M3G_FALSE); |
|
952 } |
997 } |
953 } |
998 } |
954 else { |
999 else { |
955 /* Buffered rendering is not supported for window and pbuffer |
1000 /* Buffered rendering is not supported for window and pbuffer |
956 * targets */ |
1001 * targets */ |
967 static void m3gUpdateTargetBuffer(RenderContext *ctx) |
1012 static void m3gUpdateTargetBuffer(RenderContext *ctx) |
968 { |
1013 { |
969 if (ctx->target.type == SURFACE_IMAGE) { |
1014 if (ctx->target.type == SURFACE_IMAGE) { |
970 m3gCopyFrameBufferImage((Image *) ctx->target.handle); |
1015 m3gCopyFrameBufferImage((Image *) ctx->target.handle); |
971 } |
1016 } |
972 else if (ctx->target.type == SURFACE_BITMAP) { |
1017 else if (ctx->target.type == SURFACE_BITMAP || ctx->target.type == SURFACE_MEMORY) { |
973 |
1018 |
974 /* We must copy the back buffer to a native bitmap: first |
1019 M3GPixelFormat format = ctx->target.format; |
975 * attempt a fast buffer-to-buffer copy using EGL, but if that |
1020 M3Gint width = ctx->clip.x1 - ctx->clip.x0; |
976 * fails, obtain a pointer and do the copy ourselves */ |
1021 M3Gint height = ctx->clip.y1 - ctx->clip.y0; |
977 |
1022 M3Gint xOffset = ctx->clip.x0; |
978 /* We can only do the fast copy for the full buffer */ |
1023 M3Gint yOffset = ctx->clip.y0; |
979 |
1024 M3Gint row; |
980 M3Gbool fullClip = (ctx->clip.x0 == 0) |
1025 |
981 && (ctx->clip.y0 <= ctx->target.height - ctx->display.height) |
1026 M3Gubyte *dst; |
982 && (ctx->clip.x1 >= ctx->display.width) |
1027 M3Gsizei stride; |
983 && (ctx->clip.y1 >= ctx->clip.y0 + ctx->display.height); |
1028 M3Gubyte *temp; |
984 |
1029 |
985 if (!fullClip || !eglCopyBuffers(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
1030 if (ctx->target.type == SURFACE_BITMAP) { |
986 ctx->backBuffer.glSurface, |
1031 /* We must copy the back buffer to a native bitmap: first |
987 (NativePixmapType) ctx->target.handle)) { |
1032 * attempt a fast buffer-to-buffer copy using EGL, but if that |
|
1033 * fails, obtain a pointer and do the copy ourselves */ |
|
1034 |
|
1035 /* We can only do the fast copy for the full buffer */ |
|
1036 |
|
1037 M3Gbool fullClip = (ctx->clip.x0 == 0) |
|
1038 && (ctx->clip.y0 <= ctx->target.height - ctx->display.height) |
|
1039 && (ctx->clip.x1 >= ctx->display.width) |
|
1040 && (ctx->clip.y1 >= ctx->clip.y0 + ctx->display.height); |
|
1041 |
|
1042 if (fullClip && eglCopyBuffers(eglGetDisplay(EGL_DEFAULT_DISPLAY), |
|
1043 ctx->backBuffer.glSurface, |
|
1044 (NativePixmapType) ctx->target.handle)) |
|
1045 { |
|
1046 return; |
|
1047 } |
988 |
1048 |
989 /* Fast copy failed, try the generic approach */ |
1049 /* Fast copy failed, try the generic approach */ |
990 |
1050 if (!m3gglLockNativeBitmap((M3GNativeBitmap) ctx->target.handle, |
991 M3Gubyte *dst; |
|
992 M3Gsizei stride; |
|
993 |
|
994 if (m3gglLockNativeBitmap((M3GNativeBitmap) ctx->target.handle, |
|
995 &dst, &stride)) { |
1051 &dst, &stride)) { |
996 |
|
997 /* OK, got the pointer; now, copy a scanline at a |
|
998 * time, and we can pretty much assume conversion |
|
999 * since the fast method didn't work */ |
|
1000 |
|
1001 M3GPixelFormat format = ctx->target.format; |
|
1002 M3Gint width = ctx->clip.x1 - ctx->clip.x0; |
|
1003 M3Gint height = ctx->clip.y1 - ctx->clip.y0; |
|
1004 M3Gint xOffset = ctx->clip.x0; |
|
1005 M3Gint yOffset = ctx->clip.y0; |
|
1006 M3Gint row; |
|
1007 |
|
1008 M3Gubyte *temp = m3gAllocTemp(M3G_INTERFACE(ctx), width * 4); |
|
1009 if (!temp) { |
|
1010 return; /* out of memory */ |
|
1011 } |
|
1012 |
|
1013 dst += (ctx->target.height - (yOffset + height)) * stride |
|
1014 + xOffset * m3gBytesPerPixel(format); |
|
1015 |
|
1016 for (row = 0; row < height; ++row) { |
|
1017 glReadPixels(xOffset, yOffset + height - row - 1, |
|
1018 width, 1, |
|
1019 GL_RGBA, GL_UNSIGNED_BYTE, |
|
1020 temp); |
|
1021 m3gConvertPixels(M3G_RGBA8, temp, format, dst, width); |
|
1022 dst += stride; |
|
1023 } |
|
1024 m3gFreeTemp(M3G_INTERFACE(ctx)); |
|
1025 |
|
1026 m3gglReleaseNativeBitmap((M3GNativeBitmap) ctx->target.handle); |
|
1027 } |
|
1028 else { |
|
1029 /* No dice! There's no way that we know of to copy the |
1052 /* No dice! There's no way that we know of to copy the |
1030 * data between the buffers */ |
1053 * data between the buffers */ |
1031 M3G_ASSERT(M3G_FALSE); |
1054 M3G_ASSERT(M3G_FALSE); |
1032 } |
1055 } |
|
1056 } else { |
|
1057 /* Memory target */ |
|
1058 dst = ctx->target.pixels; |
|
1059 stride = ctx->target.stride; |
|
1060 } |
|
1061 |
|
1062 /* OK, got the pointer; now, copy a scanline at a |
|
1063 * time, and we can pretty much assume conversion |
|
1064 * since the fast method didn't work */ |
|
1065 |
|
1066 temp = m3gAllocTemp(M3G_INTERFACE(ctx), width * 4); |
|
1067 if (!temp) { |
|
1068 return; /* out of memory */ |
|
1069 } |
|
1070 |
|
1071 dst += (ctx->target.height - (yOffset + height)) * stride |
|
1072 + xOffset * m3gBytesPerPixel(format); |
|
1073 |
|
1074 for (row = 0; row < height; ++row) { |
|
1075 glReadPixels(xOffset, yOffset + height - row - 1, |
|
1076 width, 1, |
|
1077 GL_RGBA, GL_UNSIGNED_BYTE, |
|
1078 temp); |
|
1079 m3gConvertPixels(M3G_RGBA8, temp, format, dst, width); |
|
1080 dst += stride; |
|
1081 } |
|
1082 m3gFreeTemp(M3G_INTERFACE(ctx)); |
|
1083 |
|
1084 if (ctx->target.type == SURFACE_BITMAP) { |
|
1085 m3gglReleaseNativeBitmap((M3GNativeBitmap) ctx->target.handle); |
1033 } |
1086 } |
1034 } |
1087 } |
1035 else { |
1088 else { |
1036 /* Buffered rendering is not supported for window and pbuffer |
1089 /* Buffered rendering is not supported for window and pbuffer |
1037 * targets */ |
1090 * targets */ |
1100 |
1153 |
1101 /* Create a new GL context, then delete the LRU one. This is |
1154 /* Create a new GL context, then delete the LRU one. This is |
1102 * done in this order so that we don't lose any shared texture |
1155 * done in this order so that we don't lose any shared texture |
1103 * objects when deleting a context. */ |
1156 * objects when deleting a context. */ |
1104 |
1157 |
1105 if (surfaceTypeBits == SURFACE_EGL) { |
1158 //if (surfaceTypeBits == SURFACE_EGL) |
|
1159 { |
1106 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
1160 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
1107 EGLint configID; |
1161 EGLint configID; |
1108 eglQuerySurface(dpy, |
1162 eglQuerySurface(dpy, |
1109 (EGLSurface) ctx->target.handle, |
1163 surface,//(EGLSurface) ctx->target.handle, |
1110 EGL_CONFIG_ID, |
1164 EGL_CONFIG_ID, |
1111 &configID); |
1165 &configID); |
1112 glrc = eglCreateContext(dpy, (EGLConfig) configID, shareRc, NULL); |
1166 glrc = eglCreateContext(dpy, (EGLConfig) configID, shareRc, NULL); |
1113 M3G_ASSERT(glrc); |
1167 //M3G_ASSERT(glrc); |
1114 } |
1168 } |
1115 else { |
1169 /*else { |
1116 glrc = m3gCreateGLContext(format, |
1170 glrc = m3gCreateGLContext(format, |
1117 bufferBits, |
1171 bufferBits, |
1118 surfaceTypeBits, |
1172 surfaceTypeBits, |
1119 shareRc, |
1173 shareRc, |
1120 &lru->surfaceTypeBits); |
1174 &lru->surfaceTypeBits); |
1121 } |
1175 } |
1122 |
1176 */ |
1123 if (!glrc) { |
1177 if (!glrc) { |
1124 m3gRaiseError(M3G_INTERFACE(ctx), M3G_OUT_OF_MEMORY); |
1178 m3gRaiseError(M3G_INTERFACE(ctx), M3G_OUT_OF_MEMORY); |
1125 return NULL; |
1179 return NULL; |
1126 } |
1180 } |
1127 if (lru->handle) { |
1181 if (lru->handle) { |
1179 /* Find the first matching surface and return it */ |
1233 /* Find the first matching surface and return it */ |
1180 |
1234 |
1181 for (i = 0; i < M3G_MAX_GL_SURFACES; ++i) { |
1235 for (i = 0; i < M3G_MAX_GL_SURFACES; ++i) { |
1182 GLSurfaceRecord *surf = &ctx->glSurface[i]; |
1236 GLSurfaceRecord *surf = &ctx->glSurface[i]; |
1183 |
1237 |
1184 if (surf->type == ctx->target.type |
1238 if ((surf->type == ctx->target.type) |
1185 && surf->targetHandle == ctx->target.handle |
1239 && (surf->targetHandle == ctx->target.handle) |
1186 && (ctx->bufferBits & surf->bufferBits) == ctx->bufferBits) { |
1240 && ((ctx->bufferBits & surf->bufferBits) == ctx->bufferBits) |
|
1241 && (surf->width == ctx->target.width) |
|
1242 && (surf->height == ctx->target.height) |
|
1243 && (surf->format == ctx->target.format) |
|
1244 && (surf->pixels == ctx->target.pixels)) { |
1187 |
1245 |
1188 surf->lastUseTime = ctx->cacheTimeStamp; |
1246 surf->lastUseTime = ctx->cacheTimeStamp; |
1189 return surf->handle; |
1247 return surf->handle; |
1190 } |
1248 } |
1191 } |
1249 } |
1355 */ |
1419 */ |
1356 void m3gBindBitmapTarget(M3GRenderContext hCtx, |
1420 void m3gBindBitmapTarget(M3GRenderContext hCtx, |
1357 M3GNativeBitmap hBitmap) |
1421 M3GNativeBitmap hBitmap) |
1358 { |
1422 { |
1359 M3GPixelFormat format; |
1423 M3GPixelFormat format; |
1360 M3Gint width, height; |
1424 M3Gint width, height, pixels; |
1361 RenderContext *ctx = (RenderContext *) hCtx; |
1425 RenderContext *ctx = (RenderContext *) hCtx; |
1362 M3G_VALIDATE_OBJECT(ctx); |
1426 M3G_VALIDATE_OBJECT(ctx); |
1363 |
1427 |
1364 M3G_LOG1(M3G_LOG_RENDERING, "Binding bitmap 0x%08X\n", (unsigned) hBitmap); |
1428 M3G_LOG1(M3G_LOG_RENDERING, "Binding bitmap 0x%08X\n", (unsigned) hBitmap); |
1365 |
1429 |
1366 if (!m3gglGetNativeBitmapParams(hBitmap, &format, &width, &height)) { |
1430 if (!m3gglGetNativeBitmapParams(hBitmap, &format, &width, &height, &pixels)) { |
1367 m3gRaiseError(M3G_INTERFACE(ctx), M3G_INVALID_OBJECT); |
1431 m3gRaiseError(M3G_INTERFACE(ctx), M3G_INVALID_OBJECT); |
1368 return; |
1432 return; |
1369 } |
1433 } |
1370 |
1434 |
1371 if (!m3gBindRenderTarget(ctx, |
1435 if (!m3gBindRenderTarget(ctx, |
1415 /* placeholder for target type specific setup */ |
1482 /* placeholder for target type specific setup */ |
1416 } |
1483 } |
1417 } |
1484 } |
1418 |
1485 |
1419 /*! |
1486 /*! |
1420 * \brief Unsupported with OpenGL ES |
1487 * \brief Binds a new memory rendering target to this rendering |
1421 */ |
1488 * context |
1422 /*@access EGLContext@*/ |
1489 * |
1423 M3G_API void m3gBindMemoryTarget(M3GRenderContext context, |
1490 * Upon first binding of a specific target, binding the buffer may |
1424 /*@shared@*/ void *pixels, |
1491 * require auxiliary data to be allocated, depending on the rendering |
1425 M3Guint width, M3Guint height, |
1492 * modes set for this context. In that case, the binding will be |
1426 M3GPixelFormat format, |
1493 * canceled, and the function will return a non-zero value giving the |
1427 M3Guint stride, |
1494 * number of bytes of additional memory that needs to be supplied for |
1428 M3Guint userHandle) |
1495 * binding of that target to succeed. The function must then be called |
|
1496 * again and a pointer to a sufficient memory block supplied as the \c |
|
1497 * mem parameter. |
|
1498 * |
|
1499 * \param pixels NULL to signal that the frame buffer is accessed |
|
1500 * using a callback upon rendering time |
|
1501 */ |
|
1502 /*@access M3GGLContext@*/ |
|
1503 void m3gBindMemoryTarget(M3GRenderContext context, |
|
1504 /*@shared@*/ void *pixels, |
|
1505 M3Guint width, M3Guint height, |
|
1506 M3GPixelFormat format, |
|
1507 M3Guint stride, |
|
1508 M3Guint userHandle) |
1429 { |
1509 { |
1430 RenderContext *ctx = (RenderContext*) context; |
1510 RenderContext *ctx = (RenderContext*) context; |
1431 Interface *m3g = M3G_INTERFACE(ctx); |
1511 Interface *m3g = M3G_INTERFACE(ctx); |
1432 M3G_VALIDATE_OBJECT(ctx); |
1512 M3G_VALIDATE_OBJECT(ctx); |
1433 |
1513 |
1434 M3G_UNREF(pixels); |
1514 M3G_LOG1(M3G_LOG_RENDERING, "Binding memory buffer 0x%08X\n", |
1435 M3G_UNREF(width); |
1515 (unsigned) pixels); |
1436 M3G_UNREF(height); |
1516 |
1437 M3G_UNREF(format); |
1517 /* Check for bitmap specific errors */ |
1438 M3G_UNREF(stride); |
1518 |
1439 M3G_UNREF(userHandle); |
1519 if (width == 0 || height == 0 || stride < width) { |
1440 |
1520 m3gRaiseError(m3g, M3G_INVALID_VALUE); |
1441 m3gRaiseError(m3g, M3G_INVALID_OPERATION); |
1521 return; |
|
1522 } |
|
1523 |
|
1524 /* Effect the generic target binding */ |
|
1525 |
|
1526 if (!m3gBindRenderTarget(ctx, |
|
1527 SURFACE_MEMORY, |
|
1528 width, height, |
|
1529 format, |
|
1530 userHandle)) { |
|
1531 return; /* appropriate error raised automatically */ |
|
1532 } |
|
1533 |
|
1534 /* Set the memory target specific parameters */ |
|
1535 |
|
1536 ctx->target.pixels = pixels; |
|
1537 ctx->target.stride = stride; |
1442 } |
1538 } |
1443 |
1539 |
1444 /*! |
1540 /*! |
1445 * \brief |
1541 * \brief |
1446 */ |
1542 */ |
1513 M3G_LOG1(M3G_LOG_RENDERING, "Invalidating window 0x%08X\n", |
1609 M3G_LOG1(M3G_LOG_RENDERING, "Invalidating window 0x%08X\n", |
1514 (unsigned) hWindow); |
1610 (unsigned) hWindow); |
1515 |
1611 |
1516 m3gDeleteGLSurfaces(ctx, (M3Gbitmask) SURFACE_WINDOW, (M3Guint) hWindow); |
1612 m3gDeleteGLSurfaces(ctx, (M3Gbitmask) SURFACE_WINDOW, (M3Guint) hWindow); |
1517 } |
1613 } |
|
1614 |
|
1615 /*! |
|
1616 * \brief Invalidate a previously bound memorytarget |
|
1617 * |
|
1618 * This should be called prior to deleting a memory buffer that has |
|
1619 * been used as an M3G rendering target in the past. |
|
1620 * |
|
1621 * \param hCtx M3G rendering context |
|
1622 * \param pixels pointer to the memory buffer |
|
1623 */ |
|
1624 M3G_API void m3gInvalidateMemoryTarget(M3GRenderContext hCtx, |
|
1625 void *pixels) |
|
1626 { |
|
1627 RenderContext *ctx = (RenderContext *) hCtx; |
|
1628 M3G_VALIDATE_OBJECT(ctx); |
|
1629 |
|
1630 M3G_LOG1(M3G_LOG_RENDERING, "Invalidating memory target 0x%08X\n", |
|
1631 (unsigned) pixels); |
|
1632 |
|
1633 m3gDeleteGLSurfaces(ctx, (M3Gbitmask) SURFACE_MEMORY, (M3Guint) pixels); |
|
1634 } |