/** * Sets up a complex (shape) clip using the OpenGL depth buffer. This * method prepares the depth buffer so that the clip Region spans can * be "rendered" into it. The depth buffer is first cleared, then the * depth func is setup so that when we render the clip spans, * nothing is rendered into the color buffer, but for each pixel that would * be rendered, a non-zero value is placed into that location in the depth * buffer. With depth test enabled, pixels will only be rendered into the * color buffer if the corresponding value at that (x,y) location in the * depth buffer differs from the incoming depth value. */ void OGLContext_BeginShapeClip(OGLContext *oglc) { J2dTraceLn(J2D_TRACE_INFO, "OGLContext_BeginShapeClip"); RETURN_IF_NULL(oglc); RESET_PREVIOUS_OP(); j2d_glDisable(GL_SCISSOR_TEST); // enable depth test and clear depth buffer so that depth values are at // their maximum; also set the depth func to GL_ALWAYS so that the // depth values of the clip spans are forced into the depth buffer j2d_glEnable(GL_DEPTH_TEST); j2d_glClearDepth(1.0); j2d_glClear(GL_DEPTH_BUFFER_BIT); j2d_glDepthFunc(GL_ALWAYS); // disable writes into the color buffer while we set up the clip j2d_glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // save current transform j2d_glMatrixMode(GL_MODELVIEW); j2d_glPushMatrix(); // use identity transform plus slight translation in the z-axis when // setting the clip spans; this will push the clip spans (which would // normally be at z=0) to the z=1 plane to give them some depth j2d_glLoadIdentity(); j2d_glTranslatef(0.0f, 0.0f, 1.0f); }
void OGLPaints_ResetPaint(OGLContext *oglc) { jubyte ea; J2dTraceLn(J2D_TRACE_INFO, "OGLPaints_ResetPaint"); RETURN_IF_NULL(oglc); J2dTraceLn1(J2D_TRACE_VERBOSE, " state=%d", oglc->paintState); RESET_PREVIOUS_OP(); if (oglc->useMask) { // switch to texture unit 1, where paint state is currently enabled j2d_glActiveTextureARB(GL_TEXTURE1_ARB); } switch (oglc->paintState) { case sun_java2d_SunGraphics2D_PAINT_GRADIENT: j2d_glDisable(GL_TEXTURE_1D); j2d_glDisable(GL_TEXTURE_GEN_S); break; case sun_java2d_SunGraphics2D_PAINT_TEXTURE: // Note: The texture object used in SetTexturePaint() will // still be bound at this point, so it is safe to call the following. OGLSD_RESET_TEXTURE_WRAP(GL_TEXTURE_2D); j2d_glDisable(GL_TEXTURE_2D); j2d_glDisable(GL_TEXTURE_GEN_S); j2d_glDisable(GL_TEXTURE_GEN_T); break; case sun_java2d_SunGraphics2D_PAINT_LIN_GRADIENT: case sun_java2d_SunGraphics2D_PAINT_RAD_GRADIENT: j2d_glUseProgramObjectARB(0); j2d_glDisable(GL_TEXTURE_1D); break; case sun_java2d_SunGraphics2D_PAINT_ALPHACOLOR: default: break; } if (oglc->useMask) { // restore control to texture unit 0 j2d_glActiveTextureARB(GL_TEXTURE0_ARB); } // set each component of the current color state to the extra alpha // value, which will effectively apply the extra alpha to each fragment // in paint/texturing operations ea = (jubyte)(oglc->extraAlpha * 0xff + 0.5f); j2d_glColor4ub(ea, ea, ea, ea); oglc->pixel = (ea << 24) | (ea << 16) | (ea << 8) | (ea << 0); oglc->r = ea; oglc->g = ea; oglc->b = ea; oglc->a = ea; oglc->useMask = JNI_FALSE; oglc->paintState = -1; }
JNIEXPORT void JNICALL Java_sun_java2d_opengl_OGLMaskFill_maskFill (JNIEnv *env, jobject self, jint x, jint y, jint w, jint h, jint maskoff, jint maskscan, jint masklen, jbyteArray maskArray) { OGLContext *oglc = OGLRenderQueue_GetCurrentContext(); unsigned char *mask; J2dTraceLn(J2D_TRACE_ERROR, "OGLMaskFill_maskFill"); if (maskArray != NULL) { mask = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, maskArray, NULL); } else { mask = NULL; } OGLMaskFill_MaskFill(oglc, x, y, w, h, maskoff, maskscan, masklen, mask); // 6358147: reset current state, and ensure rendering is flushed to dest if (oglc != NULL) { RESET_PREVIOUS_OP(); j2d_glFlush(); } if (mask != NULL) { (*env)->ReleasePrimitiveArrayCritical(env, maskArray, mask, JNI_ABORT); } }
JNIEXPORT void JNICALL Java_sun_java2d_opengl_OGLTextRenderer_drawGlyphList (JNIEnv *env, jobject self, jint numGlyphs, jboolean usePositions, jboolean subPixPos, jboolean rgbOrder, jint lcdContrast, jfloat glyphListOrigX, jfloat glyphListOrigY, jlongArray imgArray, jfloatArray posArray) { unsigned char *images; J2dTraceLn(J2D_TRACE_INFO, "OGLTextRenderer_drawGlyphList"); images = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, imgArray, NULL); if (images != NULL) { OGLContext *oglc = OGLRenderQueue_GetCurrentContext(); OGLSDOps *dstOps = OGLRenderQueue_GetCurrentDestination(); if (usePositions) { unsigned char *positions = (unsigned char *) (*env)->GetPrimitiveArrayCritical(env, posArray, NULL); if (positions != NULL) { OGLTR_DrawGlyphList(env, oglc, dstOps, numGlyphs, usePositions, subPixPos, rgbOrder, lcdContrast, glyphListOrigX, glyphListOrigY, images, positions); (*env)->ReleasePrimitiveArrayCritical(env, posArray, positions, JNI_ABORT); } } else { OGLTR_DrawGlyphList(env, oglc, dstOps, numGlyphs, usePositions, subPixPos, rgbOrder, lcdContrast, glyphListOrigX, glyphListOrigY, images, NULL); } // 6358147: reset current state, and ensure rendering is // flushed to dest if (oglc != NULL) { RESET_PREVIOUS_OP(); j2d_glFlush(); } (*env)->ReleasePrimitiveArrayCritical(env, imgArray, images, JNI_ABORT); } }
/** * Finishes setting up the shape clip by resetting the depth func * so that future rendering operations will once again be written into the * color buffer (while respecting the clip set up in the depth buffer). */ void OGLContext_EndShapeClip(OGLContext *oglc, OGLSDOps *dstOps) { J2dTraceLn(J2D_TRACE_INFO, "OGLContext_EndShapeClip"); RETURN_IF_NULL(dstOps); RETURN_IF_NULL(oglc); RESET_PREVIOUS_OP(); // restore transform j2d_glPopMatrix(); // re-enable writes into the color buffer j2d_glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, (GLboolean)!dstOps->isOpaque); // enable the depth test so that only fragments within the clip region // (i.e. those fragments whose z-values are >= the values currently // stored in the depth buffer) are rendered j2d_glDepthFunc(GL_GEQUAL); }
JNIEXPORT void JNICALL Java_sun_java2d_opengl_OGLRenderer_drawPoly (JNIEnv *env, jobject oglr, jintArray xpointsArray, jintArray ypointsArray, jint nPoints, jboolean isClosed, jint transX, jint transY) { jint *xPoints, *yPoints; J2dTraceLn(J2D_TRACE_INFO, "OGLRenderer_drawPoly"); xPoints = (jint *) (*env)->GetPrimitiveArrayCritical(env, xpointsArray, NULL); if (xPoints != NULL) { yPoints = (jint *) (*env)->GetPrimitiveArrayCritical(env, ypointsArray, NULL); if (yPoints != NULL) { OGLContext *oglc = OGLRenderQueue_GetCurrentContext(); OGLRenderer_DrawPoly(oglc, nPoints, isClosed, transX, transY, xPoints, yPoints); // 6358147: reset current state, and ensure rendering is // flushed to dest if (oglc != NULL) { RESET_PREVIOUS_OP(); j2d_glFlush(); } (*env)->ReleasePrimitiveArrayCritical(env, ypointsArray, yPoints, JNI_ABORT); } (*env)->ReleasePrimitiveArrayCritical(env, xpointsArray, xPoints, JNI_ABORT); } }
/* * Class: sun_java2d_opengl_WGLSurfaceData * Method: updateWindowAccelImpl * Signature: (JJII)Z */ JNIEXPORT jboolean JNICALL Java_sun_java2d_opengl_WGLSurfaceData_updateWindowAccelImpl (JNIEnv *env, jclass clazz, jlong pData, jobject peer, jint w, jint h) { OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); OGLPixelFormat pf = PixelFormats[0/*PF_INT_ARGB_PRE*/]; HBITMAP hBitmap = NULL; void *pDst; jint srcx, srcy, dstx, dsty, width, height; jint pixelStride = 4; jint scanStride = pixelStride * w; J2dTraceLn(J2D_TRACE_INFO, "WGLSurfaceData_updateWindowAccelImpl"); if (w <= 0 || h <= 0) { return JNI_TRUE; } if (oglsdo == NULL) { return JNI_FALSE; } RESET_PREVIOUS_OP(); width = w; height = h; srcx = srcy = dstx = dsty = 0; pDst = malloc(height * scanStride); if (pDst == NULL) { return JNI_FALSE; } ZeroMemory(pDst, height * scanStride); // the code below is mostly copied from OGLBlitLoops_SurfaceToSwBlit j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, dstx); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, scanStride / pixelStride); j2d_glPixelStorei(GL_PACK_ALIGNMENT, pf.alignment); // this accounts for lower-left origin of the source region srcx = oglsdo->xOffset + srcx; srcy = oglsdo->yOffset + oglsdo->height - (srcy + 1); // we must read one scanline at a time because there is no way // to read starting at the top-left corner of the source region while (height > 0) { j2d_glPixelStorei(GL_PACK_SKIP_ROWS, dsty); j2d_glReadPixels(srcx, srcy, width, 1, pf.format, pf.type, pDst); srcy--; dsty++; height--; } j2d_glPixelStorei(GL_PACK_SKIP_PIXELS, 0); j2d_glPixelStorei(GL_PACK_SKIP_ROWS, 0); j2d_glPixelStorei(GL_PACK_ROW_LENGTH, 0); j2d_glPixelStorei(GL_PACK_ALIGNMENT, 4); // the pixels read from the surface are already premultiplied // REMIND: commented until translucent window support is integrated // hBitmap = BitmapUtil_CreateBitmapFromARGBPre(w, h, scanStride, // (int*)pDst); free(pDst); if (hBitmap == NULL) { return JNI_FALSE; } // REMIND: commented until translucent window support is integrated // AwtWindow_UpdateWindow(env, peer, w, h, hBitmap); // hBitmap is released in UpdateWindow return JNI_TRUE; }
JNIEXPORT void JNICALL Java_sun_java2d_opengl_OGLRenderQueue_flushBuffer (JNIEnv *env, jobject oglrq, jlong buf, jint limit) { jboolean sync = JNI_FALSE; unsigned char *b, *end; J2dTraceLn1(J2D_TRACE_INFO, "OGLRenderQueue_flushBuffer: limit=%d", limit); b = (unsigned char *)jlong_to_ptr(buf); if (b == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLRenderQueue_flushBuffer: cannot get direct buffer address"); return; } INIT_PREVIOUS_OP(); end = b + limit; while (b < end) { jint opcode = NEXT_INT(b); J2dTraceLn2(J2D_TRACE_VERBOSE, "OGLRenderQueue_flushBuffer: opcode=%d, rem=%d", opcode, (end-b)); switch (opcode) { // draw ops case sun_java2d_pipe_BufferedOpCodes_DRAW_LINE: { jint x1 = NEXT_INT(b); jint y1 = NEXT_INT(b); jint x2 = NEXT_INT(b); jint y2 = NEXT_INT(b); OGLRenderer_DrawLine(oglc, x1, y1, x2, y2); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_RECT: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); OGLRenderer_DrawRect(oglc, x, y, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_POLY: { jint nPoints = NEXT_INT(b); jboolean isClosed = NEXT_BOOLEAN(b); jint transX = NEXT_INT(b); jint transY = NEXT_INT(b); jint *xPoints = (jint *)b; jint *yPoints = ((jint *)b) + nPoints; OGLRenderer_DrawPoly(oglc, nPoints, isClosed, transX, transY, xPoints, yPoints); SKIP_BYTES(b, nPoints * BYTES_PER_POLY_POINT); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_PIXEL: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); // Note that we could use GL_POINTS here, but the common // use case for DRAW_PIXEL is when rendering a Path2D, // which will consist of a mix of DRAW_PIXEL and DRAW_LINE // calls. So to improve batching we use GL_LINES here, // even though it requires an extra vertex per pixel. CONTINUE_IF_NULL(oglc); CHECK_PREVIOUS_OP(GL_LINES); j2d_glVertex2i(x, y); j2d_glVertex2i(x+1, y+1); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_SCANLINES: { jint count = NEXT_INT(b); OGLRenderer_DrawScanlines(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SCANLINE); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_PARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); jfloat lwr21 = NEXT_FLOAT(b); jfloat lwr12 = NEXT_FLOAT(b); OGLRenderer_DrawParallelogram(oglc, x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12); } break; case sun_java2d_pipe_BufferedOpCodes_DRAW_AAPARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); jfloat lwr21 = NEXT_FLOAT(b); jfloat lwr12 = NEXT_FLOAT(b); OGLRenderer_DrawAAParallelogram(oglc, dstOps, x11, y11, dx21, dy21, dx12, dy12, lwr21, lwr12); } break; // fill ops case sun_java2d_pipe_BufferedOpCodes_FILL_RECT: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); OGLRenderer_FillRect(oglc, x, y, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_SPANS: { jint count = NEXT_INT(b); OGLRenderer_FillSpans(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SPAN); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_PARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); OGLRenderer_FillParallelogram(oglc, x11, y11, dx21, dy21, dx12, dy12); } break; case sun_java2d_pipe_BufferedOpCodes_FILL_AAPARALLELOGRAM: { jfloat x11 = NEXT_FLOAT(b); jfloat y11 = NEXT_FLOAT(b); jfloat dx21 = NEXT_FLOAT(b); jfloat dy21 = NEXT_FLOAT(b); jfloat dx12 = NEXT_FLOAT(b); jfloat dy12 = NEXT_FLOAT(b); OGLRenderer_FillAAParallelogram(oglc, dstOps, x11, y11, dx21, dy21, dx12, dy12); } break; // text-related ops case sun_java2d_pipe_BufferedOpCodes_DRAW_GLYPH_LIST: { jint numGlyphs = NEXT_INT(b); jint packedParams = NEXT_INT(b); jfloat glyphListOrigX = NEXT_FLOAT(b); jfloat glyphListOrigY = NEXT_FLOAT(b); jboolean usePositions = EXTRACT_BOOLEAN(packedParams, OFFSET_POSITIONS); jboolean subPixPos = EXTRACT_BOOLEAN(packedParams, OFFSET_SUBPIXPOS); jboolean rgbOrder = EXTRACT_BOOLEAN(packedParams, OFFSET_RGBORDER); jint lcdContrast = EXTRACT_BYTE(packedParams, OFFSET_CONTRAST); unsigned char *images = b; unsigned char *positions; jint bytesPerGlyph; if (usePositions) { positions = (b + numGlyphs * BYTES_PER_GLYPH_IMAGE); bytesPerGlyph = BYTES_PER_POSITIONED_GLYPH; } else { positions = NULL; bytesPerGlyph = BYTES_PER_GLYPH_IMAGE; } OGLTR_DrawGlyphList(env, oglc, dstOps, numGlyphs, usePositions, subPixPos, rgbOrder, lcdContrast, glyphListOrigX, glyphListOrigY, images, positions); SKIP_BYTES(b, numGlyphs * bytesPerGlyph); } break; // copy-related ops case sun_java2d_pipe_BufferedOpCodes_COPY_AREA: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint dx = NEXT_INT(b); jint dy = NEXT_INT(b); OGLBlitLoops_CopyArea(env, oglc, dstOps, x, y, w, h, dx, dy); } break; case sun_java2d_pipe_BufferedOpCodes_BLIT: { jint packedParams = NEXT_INT(b); jint sx1 = NEXT_INT(b); jint sy1 = NEXT_INT(b); jint sx2 = NEXT_INT(b); jint sy2 = NEXT_INT(b); jdouble dx1 = NEXT_DOUBLE(b); jdouble dy1 = NEXT_DOUBLE(b); jdouble dx2 = NEXT_DOUBLE(b); jdouble dy2 = NEXT_DOUBLE(b); jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); jint hint = EXTRACT_BYTE(packedParams, OFFSET_HINT); jboolean texture = EXTRACT_BOOLEAN(packedParams, OFFSET_TEXTURE); jboolean rtt = EXTRACT_BOOLEAN(packedParams, OFFSET_RTT); jboolean xform = EXTRACT_BOOLEAN(packedParams, OFFSET_XFORM); jboolean isoblit = EXTRACT_BOOLEAN(packedParams, OFFSET_ISOBLIT); if (isoblit) { OGLBlitLoops_IsoBlit(env, oglc, pSrc, pDst, xform, hint, texture, rtt, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } else { jint srctype = EXTRACT_BYTE(packedParams, OFFSET_SRCTYPE); OGLBlitLoops_Blit(env, oglc, pSrc, pDst, xform, hint, srctype, texture, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); } } break; case sun_java2d_pipe_BufferedOpCodes_SURFACE_TO_SW_BLIT: { jint sx = NEXT_INT(b); jint sy = NEXT_INT(b); jint dx = NEXT_INT(b); jint dy = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint dsttype = NEXT_INT(b); jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); OGLBlitLoops_SurfaceToSwBlit(env, oglc, pSrc, pDst, dsttype, sx, sy, dx, dy, w, h); } break; case sun_java2d_pipe_BufferedOpCodes_MASK_FILL: { jint x = NEXT_INT(b); jint y = NEXT_INT(b); jint w = NEXT_INT(b); jint h = NEXT_INT(b); jint maskoff = NEXT_INT(b); jint maskscan = NEXT_INT(b); jint masklen = NEXT_INT(b); unsigned char *pMask = (masklen > 0) ? b : NULL; OGLMaskFill_MaskFill(oglc, x, y, w, h, maskoff, maskscan, masklen, pMask); SKIP_BYTES(b, masklen); } break; case sun_java2d_pipe_BufferedOpCodes_MASK_BLIT: { jint dstx = NEXT_INT(b); jint dsty = NEXT_INT(b); jint width = NEXT_INT(b); jint height = NEXT_INT(b); jint masklen = width * height * sizeof(jint); OGLMaskBlit_MaskBlit(env, oglc, dstx, dsty, width, height, b); SKIP_BYTES(b, masklen); } break; // state-related ops case sun_java2d_pipe_BufferedOpCodes_SET_RECT_CLIP: { jint x1 = NEXT_INT(b); jint y1 = NEXT_INT(b); jint x2 = NEXT_INT(b); jint y2 = NEXT_INT(b); OGLContext_SetRectClip(oglc, dstOps, x1, y1, x2, y2); } break; case sun_java2d_pipe_BufferedOpCodes_BEGIN_SHAPE_CLIP: { OGLContext_BeginShapeClip(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_SHAPE_CLIP_SPANS: { jint count = NEXT_INT(b); OGLRenderer_FillSpans(oglc, count, (jint *)b); SKIP_BYTES(b, count * BYTES_PER_SPAN); } break; case sun_java2d_pipe_BufferedOpCodes_END_SHAPE_CLIP: { OGLContext_EndShapeClip(oglc, dstOps); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_CLIP: { OGLContext_ResetClip(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_ALPHA_COMPOSITE: { jint rule = NEXT_INT(b); jfloat extraAlpha = NEXT_FLOAT(b); jint flags = NEXT_INT(b); OGLContext_SetAlphaComposite(oglc, rule, extraAlpha, flags); } break; case sun_java2d_pipe_BufferedOpCodes_SET_XOR_COMPOSITE: { jint xorPixel = NEXT_INT(b); OGLContext_SetXorComposite(oglc, xorPixel); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_COMPOSITE: { OGLContext_ResetComposite(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_TRANSFORM: { jdouble m00 = NEXT_DOUBLE(b); jdouble m10 = NEXT_DOUBLE(b); jdouble m01 = NEXT_DOUBLE(b); jdouble m11 = NEXT_DOUBLE(b); jdouble m02 = NEXT_DOUBLE(b); jdouble m12 = NEXT_DOUBLE(b); OGLContext_SetTransform(oglc, m00, m10, m01, m11, m02, m12); } break; case sun_java2d_pipe_BufferedOpCodes_RESET_TRANSFORM: { OGLContext_ResetTransform(oglc); } break; // context-related ops case sun_java2d_pipe_BufferedOpCodes_SET_SURFACES: { jlong pSrc = NEXT_LONG(b); jlong pDst = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } oglc = OGLContext_SetSurfaces(env, pSrc, pDst); dstOps = (OGLSDOps *)jlong_to_ptr(pDst); } break; case sun_java2d_pipe_BufferedOpCodes_SET_SCRATCH_SURFACE: { jlong pConfigInfo = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } oglc = OGLSD_SetScratchSurface(env, pConfigInfo); dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_FLUSH_SURFACE: { jlong pData = NEXT_LONG(b); OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); if (oglsdo != NULL) { CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLSD_Delete(env, oglsdo); } } break; case sun_java2d_pipe_BufferedOpCodes_DISPOSE_SURFACE: { jlong pData = NEXT_LONG(b); OGLSDOps *oglsdo = (OGLSDOps *)jlong_to_ptr(pData); if (oglsdo != NULL) { CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLSD_Delete(env, oglsdo); if (oglsdo->privOps != NULL) { free(oglsdo->privOps); } } } break; case sun_java2d_pipe_BufferedOpCodes_DISPOSE_CONFIG: { jlong pConfigInfo = NEXT_LONG(b); CONTINUE_IF_NULL(oglc); RESET_PREVIOUS_OP(); OGLGC_DestroyOGLGraphicsConfig(pConfigInfo); // the previous method will call glX/wglMakeCurrent(None), // so we should nullify the current oglc and dstOps to avoid // calling glFlush() (or similar) while no context is current oglc = NULL; dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_INVALIDATE_CONTEXT: { // flush just in case there are any pending operations in // the hardware pipe if (oglc != NULL) { RESET_PREVIOUS_OP(); j2d_glFlush(); } // invalidate the references to the current context and // destination surface that are maintained at the native level oglc = NULL; dstOps = NULL; } break; case sun_java2d_pipe_BufferedOpCodes_SAVE_STATE: { j2d_glPushAttrib(GL_ALL_ATTRIB_BITS); j2d_glPushClientAttrib(GL_CLIENT_ALL_ATTRIB_BITS); j2d_glMatrixMode(GL_MODELVIEW); j2d_glPushMatrix(); j2d_glMatrixMode(GL_PROJECTION); j2d_glPushMatrix(); j2d_glMatrixMode(GL_TEXTURE); j2d_glPushMatrix(); } break; case sun_java2d_pipe_BufferedOpCodes_RESTORE_STATE: { j2d_glPopAttrib(); j2d_glPopClientAttrib(); j2d_glMatrixMode(GL_MODELVIEW); j2d_glPopMatrix(); j2d_glMatrixMode(GL_PROJECTION); j2d_glPopMatrix(); j2d_glMatrixMode(GL_TEXTURE); j2d_glPopMatrix(); } break; case sun_java2d_pipe_BufferedOpCodes_SYNC: { sync = JNI_TRUE; } break; // multibuffering ops case sun_java2d_pipe_BufferedOpCodes_SWAP_BUFFERS: { jlong window = NEXT_LONG(b); if (oglc != NULL) { RESET_PREVIOUS_OP(); } OGLSD_SwapBuffers(env, window); } break; // special no-op (mainly used for achieving 8-byte alignment) case sun_java2d_pipe_BufferedOpCodes_NOOP: break; // paint-related ops case sun_java2d_pipe_BufferedOpCodes_RESET_PAINT: { OGLPaints_ResetPaint(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_SET_COLOR: { jint pixel = NEXT_INT(b); OGLPaints_SetColor(oglc, pixel); } break; case sun_java2d_pipe_BufferedOpCodes_SET_GRADIENT_PAINT: { jboolean useMask= NEXT_BOOLEAN(b); jboolean cyclic = NEXT_BOOLEAN(b); jdouble p0 = NEXT_DOUBLE(b); jdouble p1 = NEXT_DOUBLE(b); jdouble p3 = NEXT_DOUBLE(b); jint pixel1 = NEXT_INT(b); jint pixel2 = NEXT_INT(b); OGLPaints_SetGradientPaint(oglc, useMask, cyclic, p0, p1, p3, pixel1, pixel2); } break; case sun_java2d_pipe_BufferedOpCodes_SET_LINEAR_GRADIENT_PAINT: { jboolean useMask = NEXT_BOOLEAN(b); jboolean linear = NEXT_BOOLEAN(b); jint cycleMethod = NEXT_INT(b); jint numStops = NEXT_INT(b); jfloat p0 = NEXT_FLOAT(b); jfloat p1 = NEXT_FLOAT(b); jfloat p3 = NEXT_FLOAT(b); void *fractions, *pixels; fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); OGLPaints_SetLinearGradientPaint(oglc, dstOps, useMask, linear, cycleMethod, numStops, p0, p1, p3, fractions, pixels); } break; case sun_java2d_pipe_BufferedOpCodes_SET_RADIAL_GRADIENT_PAINT: { jboolean useMask = NEXT_BOOLEAN(b); jboolean linear = NEXT_BOOLEAN(b); jint numStops = NEXT_INT(b); jint cycleMethod = NEXT_INT(b); jfloat m00 = NEXT_FLOAT(b); jfloat m01 = NEXT_FLOAT(b); jfloat m02 = NEXT_FLOAT(b); jfloat m10 = NEXT_FLOAT(b); jfloat m11 = NEXT_FLOAT(b); jfloat m12 = NEXT_FLOAT(b); jfloat focusX = NEXT_FLOAT(b); void *fractions, *pixels; fractions = b; SKIP_BYTES(b, numStops * sizeof(jfloat)); pixels = b; SKIP_BYTES(b, numStops * sizeof(jint)); OGLPaints_SetRadialGradientPaint(oglc, dstOps, useMask, linear, cycleMethod, numStops, m00, m01, m02, m10, m11, m12, focusX, fractions, pixels); } break; case sun_java2d_pipe_BufferedOpCodes_SET_TEXTURE_PAINT: { jboolean useMask= NEXT_BOOLEAN(b); jboolean filter = NEXT_BOOLEAN(b); jlong pSrc = NEXT_LONG(b); jdouble xp0 = NEXT_DOUBLE(b); jdouble xp1 = NEXT_DOUBLE(b); jdouble xp3 = NEXT_DOUBLE(b); jdouble yp0 = NEXT_DOUBLE(b); jdouble yp1 = NEXT_DOUBLE(b); jdouble yp3 = NEXT_DOUBLE(b); OGLPaints_SetTexturePaint(oglc, useMask, pSrc, filter, xp0, xp1, xp3, yp0, yp1, yp3); } break; // BufferedImageOp-related ops case sun_java2d_pipe_BufferedOpCodes_ENABLE_CONVOLVE_OP: { jlong pSrc = NEXT_LONG(b); jboolean edgeZero = NEXT_BOOLEAN(b); jint kernelWidth = NEXT_INT(b); jint kernelHeight = NEXT_INT(b); OGLBufImgOps_EnableConvolveOp(oglc, pSrc, edgeZero, kernelWidth, kernelHeight, b); SKIP_BYTES(b, kernelWidth * kernelHeight * sizeof(jfloat)); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_CONVOLVE_OP: { OGLBufImgOps_DisableConvolveOp(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_ENABLE_RESCALE_OP: { jlong pSrc = NEXT_LONG(b); jboolean nonPremult = NEXT_BOOLEAN(b); jint numFactors = 4; unsigned char *scaleFactors = b; unsigned char *offsets = (b + numFactors * sizeof(jfloat)); OGLBufImgOps_EnableRescaleOp(oglc, pSrc, nonPremult, scaleFactors, offsets); SKIP_BYTES(b, numFactors * sizeof(jfloat) * 2); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_RESCALE_OP: { OGLBufImgOps_DisableRescaleOp(oglc); } break; case sun_java2d_pipe_BufferedOpCodes_ENABLE_LOOKUP_OP: { jlong pSrc = NEXT_LONG(b); jboolean nonPremult = NEXT_BOOLEAN(b); jboolean shortData = NEXT_BOOLEAN(b); jint numBands = NEXT_INT(b); jint bandLength = NEXT_INT(b); jint offset = NEXT_INT(b); jint bytesPerElem = shortData ? sizeof(jshort):sizeof(jbyte); void *tableValues = b; OGLBufImgOps_EnableLookupOp(oglc, pSrc, nonPremult, shortData, numBands, bandLength, offset, tableValues); SKIP_BYTES(b, numBands * bandLength * bytesPerElem); } break; case sun_java2d_pipe_BufferedOpCodes_DISABLE_LOOKUP_OP: { OGLBufImgOps_DisableLookupOp(oglc); } break; default: J2dRlsTraceLn1(J2D_TRACE_ERROR, "OGLRenderQueue_flushBuffer: invalid opcode=%d", opcode); if (oglc != NULL) { RESET_PREVIOUS_OP(); } return; } } if (oglc != NULL) { RESET_PREVIOUS_OP(); if (sync) { j2d_glFinish(); } else { j2d_glFlush(); } OGLSD_Flush(env); } }
void OGLRenderer_DrawPoly(OGLContext *oglc, jint nPoints, jint isClosed, jint transX, jint transY, jint *xPoints, jint *yPoints) { jboolean isEmpty = JNI_TRUE; jint mx, my; jint i; J2dTraceLn(J2D_TRACE_INFO, "OGLRenderer_DrawPoly"); if (xPoints == NULL || yPoints == NULL) { J2dRlsTraceLn(J2D_TRACE_ERROR, "OGLRenderer_DrawPoly: points array is null"); return; } RETURN_IF_NULL(oglc); // Note that BufferedRenderPipe.drawPoly() has already rejected polys // with nPoints<2, so we can be certain here that we have nPoints>=2. mx = xPoints[0]; my = yPoints[0]; CHECK_PREVIOUS_OP(GL_LINE_STRIP); for (i = 0; i < nPoints; i++) { jint x = xPoints[i]; jint y = yPoints[i]; isEmpty = isEmpty && (x == mx && y == my); // Translate each vertex by a fraction so that we hit pixel centers. j2d_glVertex2f((GLfloat)(x + transX) + 0.5f, (GLfloat)(y + transY) + 0.5f); } if (isClosed && !isEmpty && (xPoints[nPoints-1] != mx || yPoints[nPoints-1] != my)) { // In this case, the polyline's start and end positions are // different and need to be closed manually; we do this by adding // one more segment back to the starting position. Note that we // do not need to fill in the last pixel (as we do in the following // block) because we are returning to the starting pixel, which // has already been filled in. j2d_glVertex2f((GLfloat)(mx + transX) + 0.5f, (GLfloat)(my + transY) + 0.5f); RESET_PREVIOUS_OP(); // so that we don't leave the line strip open } else if (!isClosed || isEmpty) { // OpenGL omits the last pixel in a polyline, so we fix this by // adding a one-pixel segment at the end. Also, if the polyline // never went anywhere (isEmpty is true), we need to use this // workaround to ensure that a single pixel is touched. CHECK_PREVIOUS_OP(GL_LINES); // this closes the line strip first mx = xPoints[nPoints-1] + transX; my = yPoints[nPoints-1] + transY; j2d_glVertex2i(mx, my); j2d_glVertex2i(mx+1, my+1); // no need for RESET_PREVIOUS_OP, as the line strip is no longer open } else { RESET_PREVIOUS_OP(); // so that we don't leave the line strip open } }