Hi Jim, Passing the contentWidth to the update() fixes the problem as well, and if the excessive memory is not needed (as in my proposal), this is of course much better. Can I create an issue and suggest the following patch (this is for 8, but I can do a similar for 9)?
- Johan --- a/modules/graphics/src/main/java/com/sun/prism/impl/BaseContext.java Thu Mar 03 03:22:09 2016 +0100 +++ b/modules/graphics/src/main/java/com/sun/prism/impl/BaseContext.java Wed Mar 09 10:59:35 2016 +0100 @@ -104,7 +104,7 @@ // since it was bound and unflushed... maskTex.update(maskBuffer, maskTex.getPixelFormat(), 0, 0, 0, 0, highMaskCol, nextMaskRow, - maskTex.getPhysicalWidth(), true); + maskTex.getContentWidth(), true); maskTex.unlock(); curMaskRow = curMaskCol = nextMaskRow = highMaskCol = 0; } On Tue, Mar 8, 2016 at 10:43 PM, Jim Graham <james.gra...@oracle.com> wrote: > I think I see the issue. > > In the code that calls maskTex.update(...) it passes > maskTex.physicalWidth() as the scan stride of the buffer, but the scan > stride of the buffer is based on the content size, not the physical size. > Thus, the checkUpdateParams() method overestimates how many bytes are > consumed by the operation. > > Changing that to maskTex.getContentWidth() should be fine... > > ...jim > > On 3/8/16 6:14 AM, Johan Vos wrote: > >> We got a number of bug reports (on Android and iOS) reported by developers >> using large images: >> >> java.lang.IllegalArgumentException: Upload requires 2475266 elements, but >> only 1549938 elements remain in the buffer >> >> at com.sun.prism.impl.BaseTexture.checkUpdateParams(BaseTexture.java:354) >> >> at com.sun.prism.es2.ES2Texture.update(ES2Texture.java:640) >> >> at com.sun.prism.impl.BaseContext.flushVertexBuffer(BaseContext.java:106) >> >> at com.sun.prism.impl.BaseContext.updateMaskTexture(BaseContext.java:248) >> >> at >> com.sun.prism.impl.ps >> .BaseShaderGraphics.renderShape(BaseShaderGraphics.java:482) >> >> >> I traced this down to the following: >> >> initially, a buffer of [1024 * 1024] is allocated by >> BaseContext.validateMaskTexture. When the MaskData becomes bigger than >> 1024 >> (w or h), a new buffer is allocated with capacity [newTexW * newTexH] with >> newTexW and newTexH the new width/height that are passed when creating a >> new Texture. However, the physical size of the texture can be different -- >> e.g. >> >> ES2Texture.create (ES2Context, PixelFormat, WrapMode, int, int, bool) will >> in some cases set the real texWidth/height to the next power of 2. >> >> Subsequently, in next rendering loops when the Texture needs to be >> updated, >> it is checked whether the capacity of the buffer is large enough to hold >> the texture. In this case, the physical width is passed and the buffer is >> not large enough. >> >> Adding the following two lines in BaseContext.validateMaskTexture() (line >> 220) fixes the problem: >> >> newTexW = Math.max(newTexW, maskTex.getPhysicalWidth()); >> >> newTexH = Math.max(newTexH, maskTex.getPhysicalHeight()); >> >> Using this patch, the size of the buffer will take the physical size of >> the >> texture into account. I'm not sure this is the best approach though. >> >> - Johan >> >>