--- old/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java 2014-07-10 17:04:13.000000000 -0700 +++ new/modules/graphics/src/main/java/com/sun/javafx/sg/prism/NGCanvas.java 2014-07-10 17:04:13.000000000 -0700 @@ -53,6 +53,7 @@ import com.sun.prism.Graphics; import com.sun.prism.GraphicsPipeline; import com.sun.prism.Image; +import com.sun.prism.MaskTextureGraphics; import com.sun.prism.PrinterGraphics; import com.sun.prism.RTTexture; import com.sun.prism.ResourceFactory; @@ -673,9 +674,15 @@ renderClip(new RoundRectangle2D(clipRect.x, clipRect.y, clipRect.width, clipRect.height, 0, 0)); - clipRect = null; } } + shapebounds(clippath, TEMP_RECTBOUNDS, BaseTransform.IDENTITY_TRANSFORM); + TEMP_RECT.setBounds(TEMP_RECTBOUNDS); + if (clipRect == null) { + clipRect = new Rectangle(TEMP_RECT); + } else { + clipRect.intersectWith(TEMP_RECT); + } renderClip(clippath); } if (clipValidated && clipIsRect) { @@ -1018,12 +1025,11 @@ tempvalidated = true; dest = temp; } else if (blendmode != Blend.Mode.SRC_OVER) { - clipvalidated = false; temp.validate(cv.g, tw, th); tempvalidated = true; dest = temp; } else { - clipvalidated = tempvalidated = false; + tempvalidated = false; dest = cv; } if (effect != null) { @@ -1076,8 +1082,24 @@ // assert: dest == temp; compmode = CompositeMode.SRC; } - blendAthruBintoC(temp, Mode.SRC_IN, clip, - TEMP_RECTBOUNDS, compmode, dest); + if (clipRect != null) { + TEMP_RECTBOUNDS.intersectWith(clipRect); + } + if (!TEMP_RECTBOUNDS.isEmpty()) { + if (dest == cv && cv.g instanceof MaskTextureGraphics) { + MaskTextureGraphics mtg = (MaskTextureGraphics) cv.g; + int dx = (int) Math.floor(TEMP_RECTBOUNDS.getMinX()); + int dy = (int) Math.floor(TEMP_RECTBOUNDS.getMinY()); + int dw = (int) Math.ceil(TEMP_RECTBOUNDS.getMaxX()) - dx; + int dh = (int) Math.ceil(TEMP_RECTBOUNDS.getMaxY()) - dy; + mtg.drawPixelsMasked(temp.tex, clip.tex, + dx, dy, dw, dh, + dx, dy, dx, dy); + } else { + blendAthruBintoC(temp, Mode.SRC_IN, clip, + TEMP_RECTBOUNDS, compmode, dest); + } + } } if (blendmode != Blend.Mode.SRC_OVER) { // We always use SRC mode here because the results of