< prev index next >

modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/QuantumToolkit.java

Print this page
@@ -1518,33 +1518,21 @@
                      }
                  }
                  rt.unlock();
              }
  
-             private int computeOptimumTileSize(int size, int maxSize) {
-                 return computeOptimumTileSize(size, maxSize, null);
-             }
  
-             private int computeOptimumTileSize(int size, int maxSize, boolean[] isDivExact) {
-                 // This method attempts to find the smallest exact divider for the provided `size`
-                 // while the result of the division is less than `maxSize`.
-                 // It tests all potential dividers from 2 to 6 and returns the result of the division
-                 // if all conditions can be satisfied or, failing that, `maxSize`.
-                 // If non-null, the value for `isDivExact` is set so as to reflect whether or not
-                 // an exact divider could be found.
-                 for (int n = 2; n <= 6; n++) {
+             private int computeTileSize(int size, int maxSize) {
+                 // If 'size' divided by either 2 or 3 produce an exact result
+                 // and is lesser that the specified maxSize, then use this value
+                 // as the tile size, as this makes the tiling process more efficient.
+                 for (int n = 1; n <= 3; n++) {
                      int optimumSize = size / n;
                      if (optimumSize <= maxSize && optimumSize * n == size) {
-                         if (isDivExact != null && isDivExact.length > 0) {
-                             isDivExact[0] = true;
-                         }
                          return optimumSize;
                      }
                  }
-                 if (isDivExact != null && isDivExact.length > 0) {
-                     isDivExact[0]= false;
-                 }
                  return maxSize;
              }
  
              @Override
              public void run() {

@@ -1577,53 +1565,71 @@
                          // so we need to take several snapshot tiles and merge them into pImage
                          if (pImage.image == null) {
                              pImage.setImage(com.sun.prism.Image.fromIntArgbPreData(IntBuffer.allocate(w * h), w, h));
                          }
                          // Find out if it is possible to divide up the image in tiles of the same size
-                         int tileWidth = computeOptimumTileSize(w, maxTextureSize);
-                         var exactHeightDivFound = new boolean[]{false};
-                         int tileHeight = computeOptimumTileSize(h, maxTextureSize, exactHeightDivFound);
+                         int tileWidth = computeTileSize(w, maxTextureSize);
+                         int tileHeight = computeTileSize(h, maxTextureSize);
                          IntBuffer buffer = IntBuffer.allocate(tileWidth * tileHeight);
-                         // In order to minimize the number of time we have to resize the underlying
-                         // surface for capturing a tile, choose a dimension that has an exact divider
-                         // (if any) to be processed in the inner most loop.
-                         // E.g. looping on width then height in the example bellow requires four
-                         // surface resizing, whereas the opposite requires only two:
-                         //
-                         //       for (w;;)                    for (h;;)
-                         //           for(h;;)                     for(w;;)
-                         //       -----------------           -----------------
-                         //       |       |       |           |       |       |
-                         //       |   1   |   3   |           |   1   |   2   |
-                         //    h  |       |       |        h  |       |       |
-                         //       -----------------           -----------------
-                         //       |   2   |   4   |           |   3   |   4   |
-                         //       -----------------           -----------------
-                         //               w                           w
- 
- 
- 
-                         if (exactHeightDivFound[0]) {
-                             for (int xOffset = 0; xOffset < w; xOffset += tileWidth) {
-                                 tileWidth = Math.min(tileWidth, w - xOffset);
-                                 for (int yOffset = 0; yOffset < h; yOffset += tileHeight) {
-                                     tileHeight = Math.min(tileHeight, h - yOffset);
-                                     renderTile(x, xOffset, y, yOffset, tileWidth, tileHeight,
-                                             buffer, rf, tileRttCache, pImage);
-                                 }
-                             }
-                         } else {
-                             for (int yOffset = 0; yOffset < h; yOffset += tileHeight) {
-                                 tileHeight = Math.min(tileHeight, h - yOffset);
-                                 for (int xOffset = 0; xOffset < w; xOffset += tileWidth) {
-                                     tileWidth = Math.min(tileWidth, w - xOffset);
-                                     renderTile(x, xOffset, y, yOffset, tileWidth, tileHeight,
-                                             buffer, rf, tileRttCache, pImage);
-                                 }
+ 
+                         // M represents the middle set of tiles each with a size of tileW x tileH.
+                         // R is the right hand column of tiles,
+                         // B is the bottom row,
+                         // C is the corner:
+                         // +-----------+-----------+  .  +-------+
+                         // |           |           |  .  |       |
+                         // |     M     |     M     |  .  |   R   |
+                         // |           |           |  .  |       |
+                         // +-----------+-----------+  .  +-------+
+                         // |           |           |  .  |       |
+                         // |     M     |     M     |  .  |   R   |
+                         // |           |           |  .  |       |
+                         // +-----------+-----------+  .  +-------+
+                         //       .           .        .      .
+                         // +-----------+-----------+  .  +-------+
+                         // |     B     |     B     |  .  |   C   |
+                         // +-----------+-----------+  .  +-------+
+ 
+                         // Walk through all same-size "M" tiles
+                         int xOffset = 0;
+                         int yOffset = 0;
+                         var mTileWidth = tileWidth;
+                         var mTileHeight = tileHeight;
+                         while (mTileWidth == tileWidth && xOffset < w) {
+                             yOffset = 0;
+                             mTileHeight = tileHeight;
+                             while (mTileHeight == tileHeight && yOffset < h) {
+                                 renderTile(x, xOffset, y, yOffset, mTileWidth, mTileHeight,
+                                         buffer, rf, tileRttCache, pImage);
+                                 yOffset += tileHeight;
+                                 mTileHeight = Math.min(tileHeight, h - yOffset);
                              }
+                             xOffset += tileWidth;
+                             mTileWidth = Math.min(tileWidth, w - xOffset);
                          }
-                     } else {
+                         // Walk through remaining same-width "B" tiles, if any
+                         int bOffset = 0;
+                         int bTileHeight = tileHeight;
+                         while (bTileHeight == tileHeight && bOffset < h) {
+                             renderTile(x, xOffset, y, bOffset, mTileWidth, bTileHeight, buffer, rf, tileRttCache, pImage);
+                             bOffset += tileHeight;
+                             bTileHeight = Math.min(tileHeight, h - bOffset);
+                         }
+                         // Walk through remaining same-height "R" tiles, if any
+                         int rOffset = 0;
+                         int rTileWidth = tileWidth;
+                         while (rTileWidth == tileWidth && rOffset < w) {
+                             renderTile(x, rOffset, y, yOffset, rTileWidth, mTileHeight, buffer, rf, tileRttCache, pImage);
+                             rOffset += tileWidth;
+                             rTileWidth = Math.min(tileWidth, w - rOffset);
+                         }
+                         // Render corner "C" tile if needed
+                         if (bOffset > 0 && rOffset > 0) {
+                             renderTile(x, rOffset, y, bOffset, rTileWidth, bTileHeight, buffer, rf, tileRttCache, pImage);
+                         }
+                     }
+                     else {
                          // The requested size for the screenshot fits max texture size,
                          // so we can directly render it in the target image.
                          renderWholeImage(x, y, w, h, rf, pImage);
                      }
                      params.platformImage = pImage;
< prev index next >