Skip to content

GC.drawImage fully decodes the image file on every draw at zoom != 100 #3507

Description

@vogella

The internal drawImage(..., simple) that every public drawImage overload funnels into starts with:

ImageData srcImageData = srcImage.getImageData();
int imgWidth = srcImageData.width;
int imgHeight = srcImageData.height;

getImageData() is getImageData(100). At currentDeviceZoom != 100 that misses the zoom == currentDeviceZoom fast path and falls through to new ImageData(fileName.element()) (gtk Image.java:1270): a full open and full decode, for SVG a full re-parse and re-rasterize, to read two integers getBounds() already knows. At zoom 100 it reads the cairo surface, so the cost only shows on HiDPI.

Opens per draw (strace -f -e trace=openat, 200 draws): the 9-arg overload goes 0.00 at zoom 100 to 1.00 at zoom 200; the 5-arg overload with a stable PNG size goes 1.00 to 2.00. In an IDE startup trace at GDK_SCALE=2, 216 of 328 image-file reads below GC.drawImage came through the 9-arg overload via ImageBasedFrame.drawFrame.

Separate from #3505, which covers only the 5-arg CachedImageAtSize path; PR #3506 does not touch this one, and at zoom 200 both costs stack.

Suggested fix: take the dimensions from the known bounds instead of decoding, and obtain ImageData only where the pixels are actually needed.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions