예제 #1
0
  protected boolean scaleSurfaceData(
      SunGraphics2D sg,
      Region clipRegion,
      SurfaceData srcData,
      SurfaceData dstData,
      SurfaceType srcType,
      SurfaceType dstType,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      double dx1,
      double dy1,
      double dx2,
      double dy2) {
    CompositeType comp = sg.imageComp;
    if (CompositeType.SrcOverNoEa.equals(comp)
        && (srcData.getTransparency() == Transparency.OPAQUE)) {
      comp = CompositeType.SrcNoEa;
    }

    ScaledBlit blit = ScaledBlit.getFromCache(srcType, comp, dstType);
    if (blit != null) {
      blit.Scale(
          srcData, dstData, sg.composite, clipRegion, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
      return true;
    }
    return false;
  }
예제 #2
0
  static void Blit(
      SurfaceData srcData,
      SurfaceData dstData,
      Composite comp,
      Region clip,
      AffineTransform xform,
      int hint,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      double dx1,
      double dy1,
      double dx2,
      double dy2,
      int srctype,
      boolean texture) {
    int ctxflags = 0;
    if (srcData.getTransparency() == Transparency.OPAQUE) {
      ctxflags |= D3DContext.SRC_IS_OPAQUE;
    }

    D3DSurfaceData d3dDst = (D3DSurfaceData) dstData;
    D3DRenderQueue rq = D3DRenderQueue.getInstance();
    rq.lock();
    try {
      // make sure the RenderQueue keeps a hard reference to the
      // source (sysmem) SurfaceData to prevent it from being
      // disposed while the operation is processed on the QFT
      rq.addReference(srcData);

      if (texture) {
        // make sure we have a current context before uploading
        // the sysmem data to the texture object
        D3DContext.setScratchSurface(d3dDst.getContext());
      } else {
        D3DContext.validateContext(d3dDst, d3dDst, clip, comp, xform, null, null, ctxflags);
      }

      int packedParams = createPackedParams(false, texture, false, xform != null, hint, srctype);
      enqueueBlit(rq, srcData, dstData, packedParams, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);

      // always flush immediately, since we (currently) have no means
      // of tracking changes to the system memory surface
      rq.flushNow();
    } finally {
      rq.unlock();
    }

    if (d3dDst.getType() == D3DSurfaceData.WINDOW) {
      // flush immediately when copying to the screen to improve
      // responsiveness of applications using VI or BI backbuffers
      D3DScreenUpdateManager mgr = (D3DScreenUpdateManager) ScreenUpdateManager.getInstance();
      mgr.runUpdateNow();
    }
  }
예제 #3
0
 protected void blitSurfaceData(
     SunGraphics2D sg,
     Region clipRegion,
     SurfaceData srcData,
     SurfaceData dstData,
     SurfaceType srcType,
     SurfaceType dstType,
     int sx,
     int sy,
     int dx,
     int dy,
     int w,
     int h,
     Color bgColor) {
   if (w <= 0 || h <= 0) {
     /*
      * Fix for bugid 4783274 - BlitBg throws an exception for
      * a particular set of anomalous parameters.
      * REMIND: The native loops do proper clipping and would
      * detect this situation themselves, but the Java loops
      * all seem to trust their parameters a little too well
      * to the point where they will try to process a negative
      * area of pixels and throw exceptions.  The real fix is
      * to modify the Java loops to do proper clipping so that
      * they can deal with negative dimensions as well as
      * improperly large dimensions, but that fix is too risky
      * to integrate for Mantis at this point.  In the meantime
      * eliminating the negative or zero dimensions here is
      * "correct" and saves them from some nasty exceptional
      * conditions, one of which is the test case of 4783274.
      */
     return;
   }
   CompositeType comp = sg.imageComp;
   if (CompositeType.SrcOverNoEa.equals(comp)
       && (srcData.getTransparency() == Transparency.OPAQUE
           || (bgColor != null && bgColor.getTransparency() == Transparency.OPAQUE))) {
     comp = CompositeType.SrcNoEa;
   }
   if (!isBgOperation(srcData, bgColor)) {
     Blit blit = Blit.getFromCache(srcType, comp, dstType);
     blit.Blit(srcData, dstData, sg.composite, clipRegion, sx, sy, dx, dy, w, h);
   } else {
     BlitBg blit = BlitBg.getFromCache(srcType, comp, dstType);
     blit.BlitBg(
         srcData, dstData, sg.composite, clipRegion, bgColor.getRGB(), sx, sy, dx, dy, w, h);
   }
 }
예제 #4
0
 protected static boolean isBgOperation(SurfaceData srcData, Color bgColor) {
   // If we cannot get the srcData, then cannot assume anything about
   // the image
   return ((srcData == null)
       || ((bgColor != null) && (srcData.getTransparency() != Transparency.OPAQUE)));
 }
예제 #5
0
  protected void renderImageXform(
      SunGraphics2D sg,
      Image img,
      AffineTransform tx,
      int interpType,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      Color bgColor) {
    Region clip = sg.getCompClip();
    SurfaceData dstData = sg.surfaceData;
    SurfaceData srcData =
        dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);

    if (srcData == null) {
      img = getBufferedImage(img);
      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
      if (srcData == null) {
        // REMIND: Is this correct?  Can this happen?
        return;
      }
    }

    if (isBgOperation(srcData, bgColor)) {
      // We cannot perform bg operations during transform so make
      // an opaque temp image with the appropriate background
      // and work from there.
      img = makeBufferedImage(img, bgColor, BufferedImage.TYPE_INT_RGB, sx1, sy1, sx2, sy2);
      // Temp image has appropriate subimage at 0,0 now.
      sx2 -= sx1;
      sy2 -= sy1;
      sx1 = sy1 = 0;

      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, bgColor);
    }

    SurfaceType srcType = srcData.getSurfaceType();
    TransformHelper helper = TransformHelper.getFromCache(srcType);

    if (helper == null) {
      /* We have no helper for this source image type.
       * But we know that we do have helpers for both RGB and ARGB,
       * so convert to one of those types depending on transparency.
       * ARGB_PRE might be a better choice if the source image has
       * alpha, but it may cause some recursion here since we only
       * tend to have converters that convert to ARGB.
       */
      int type =
          ((srcData.getTransparency() == Transparency.OPAQUE)
              ? BufferedImage.TYPE_INT_RGB
              : BufferedImage.TYPE_INT_ARGB);
      img = makeBufferedImage(img, null, type, sx1, sy1, sx2, sy2);
      // Temp image has appropriate subimage at 0,0 now.
      sx2 -= sx1;
      sy2 -= sy1;
      sx1 = sy1 = 0;

      srcData = dstData.getSourceSurfaceData(img, sg.TRANSFORM_GENERIC, sg.imageComp, null);
      srcType = srcData.getSurfaceType();
      helper = TransformHelper.getFromCache(srcType);
      // assert(helper != null);
    }

    AffineTransform itx;
    try {
      itx = tx.createInverse();
    } catch (NoninvertibleTransformException e) {
      // Non-invertible transform means no output
      return;
    }

    /*
     * Find the maximum bounds on the destination that will be
     * affected by the transformed source.  First, transform all
     * four corners of the source and then min and max the resulting
     * destination coordinates of the transformed corners.
     * Note that tx already has the offset to sx1,sy1 accounted
     * for so we use the box (0, 0, sx2-sx1, sy2-sy1) as the
     * source coordinates.
     */
    double coords[] = new double[8];
    /* corner:  UL      UR      LL      LR   */
    /* index:  0  1    2  3    4  5    6  7  */
    /* coord: (0, 0), (w, 0), (0, h), (w, h) */
    coords[2] = coords[6] = sx2 - sx1;
    coords[5] = coords[7] = sy2 - sy1;
    tx.transform(coords, 0, coords, 0, 4);
    double ddx1, ddy1, ddx2, ddy2;
    ddx1 = ddx2 = coords[0];
    ddy1 = ddy2 = coords[1];
    for (int i = 2; i < coords.length; i += 2) {
      double d = coords[i];
      if (ddx1 > d) ddx1 = d;
      else if (ddx2 < d) ddx2 = d;
      d = coords[i + 1];
      if (ddy1 > d) ddy1 = d;
      else if (ddy2 < d) ddy2 = d;
    }
    int dx1 = (int) Math.floor(ddx1);
    int dy1 = (int) Math.floor(ddy1);
    int dx2 = (int) Math.ceil(ddx2);
    int dy2 = (int) Math.ceil(ddy2);

    SurfaceType dstType = dstData.getSurfaceType();
    MaskBlit maskblit;
    Blit blit;
    if (sg.compositeState <= sg.COMP_ALPHA) {
      /* NOTE: We either have, or we can make,
       * a MaskBlit for any alpha composite type
       */
      maskblit = MaskBlit.getFromCache(SurfaceType.IntArgbPre, sg.imageComp, dstType);

      /* NOTE: We can only use the native TransformHelper
       * func to go directly to the dest if both the helper
       * and the MaskBlit are native.
       * All helpers are native at this point, but some MaskBlit
       * objects are implemented in Java, so we need to check.
       */
      if (maskblit.getNativePrim() != 0) {
        // We can render directly.
        helper.Transform(
            maskblit,
            srcData,
            dstData,
            sg.composite,
            clip,
            itx,
            interpType,
            sx1,
            sy1,
            sx2,
            sy2,
            dx1,
            dy1,
            dx2,
            dy2,
            null,
            0,
            0);
        return;
      }
      blit = null;
    } else {
      /* NOTE: We either have, or we can make,
       * a Blit for any composite type, even Custom
       */
      maskblit = null;
      blit = Blit.getFromCache(SurfaceType.IntArgbPre, sg.imageComp, dstType);
    }

    // We need to transform to a temp image and then copy
    // just the pieces that are valid data to the dest.
    BufferedImage tmpimg = new BufferedImage(dx2 - dx1, dy2 - dy1, BufferedImage.TYPE_INT_ARGB);
    SurfaceData tmpData = SurfaceData.getPrimarySurfaceData(tmpimg);
    SurfaceType tmpType = tmpData.getSurfaceType();
    MaskBlit tmpmaskblit =
        MaskBlit.getFromCache(SurfaceType.IntArgbPre, CompositeType.SrcNoEa, tmpType);
    /*
     * The helper function fills a temporary edges buffer
     * for us with the bounding coordinates of each scanline
     * in the following format:
     *
     * edges[0, 1] = [top y, bottom y)
     * edges[2, 3] = [left x, right x) of top row
     * ...
     * edges[h*2, h*2+1] = [left x, right x) of bottom row
     *
     * all coordinates in the edges array will be relative to dx1, dy1
     *
     * edges thus has to be h*2+2 in length
     */
    int edges[] = new int[(dy2 - dy1) * 2 + 2];
    // It is important that edges[0]=edges[1]=0 when we call
    // Transform in case it must return early and we would
    // not want to render anything on an error condition.
    helper.Transform(
        tmpmaskblit,
        srcData,
        tmpData,
        AlphaComposite.Src,
        null,
        itx,
        interpType,
        sx1,
        sy1,
        sx2,
        sy2,
        0,
        0,
        dx2 - dx1,
        dy2 - dy1,
        edges,
        dx1,
        dy1);

    /*
     * Now copy the results, scanline by scanline, into the dest.
     * The edges array helps us minimize the work.
     */
    int index = 2;
    for (int y = edges[0]; y < edges[1]; y++) {
      int relx1 = edges[index++];
      int relx2 = edges[index++];
      if (relx1 >= relx2) {
        continue;
      }
      if (maskblit != null) {
        maskblit.MaskBlit(
            tmpData,
            dstData,
            sg.composite,
            clip,
            relx1,
            y,
            dx1 + relx1,
            dy1 + y,
            relx2 - relx1,
            1,
            null,
            0,
            0);
      } else {
        blit.Blit(
            tmpData, dstData, sg.composite, clip, relx1, y, dx1 + relx1, dy1 + y, relx2 - relx1, 1);
      }
    }
  }
예제 #6
0
  /**
   * Note: The srcImg and biop parameters are only used when invoked from the
   * D3DBufImgOps.renderImageWithOp() method; in all other cases, this method can be called with
   * null values for those two parameters, and they will be effectively ignored.
   */
  static void IsoBlit(
      SurfaceData srcData,
      SurfaceData dstData,
      BufferedImage srcImg,
      BufferedImageOp biop,
      Composite comp,
      Region clip,
      AffineTransform xform,
      int hint,
      int sx1,
      int sy1,
      int sx2,
      int sy2,
      double dx1,
      double dy1,
      double dx2,
      double dy2,
      boolean texture) {
    int ctxflags = 0;
    if (srcData.getTransparency() == Transparency.OPAQUE) {
      ctxflags |= D3DContext.SRC_IS_OPAQUE;
    }

    D3DSurfaceData d3dDst = (D3DSurfaceData) dstData;
    D3DRenderQueue rq = D3DRenderQueue.getInstance();
    boolean rtt = false;
    rq.lock();
    try {
      D3DSurfaceData d3dSrc = (D3DSurfaceData) srcData;
      int srctype = d3dSrc.getType();
      D3DSurfaceData srcCtxData = d3dSrc;
      if (srctype == D3DSurfaceData.TEXTURE) {
        rtt = false;
      } else {
        // the source is a backbuffer, or render-to-texture
        // surface; we set rtt to true to differentiate this kind
        // of surface from a regular texture object
        rtt = true;
      }

      D3DContext.validateContext(srcCtxData, d3dDst, clip, comp, xform, null, null, ctxflags);

      if (biop != null) {
        D3DBufImgOps.enableBufImgOp(rq, d3dSrc, srcImg, biop);
      }

      int packedParams = createPackedParams(true, texture, rtt, xform != null, hint, 0 /*unused*/);
      enqueueBlit(rq, srcData, dstData, packedParams, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);

      if (biop != null) {
        D3DBufImgOps.disableBufImgOp(rq, biop);
      }
    } finally {
      rq.unlock();
    }

    if (rtt && (d3dDst.getType() == D3DSurfaceData.WINDOW)) {
      // we only have to flush immediately when copying from a
      // (non-texture) surface to the screen; otherwise Swing apps
      // might appear unresponsive until the auto-flush completes
      D3DScreenUpdateManager mgr = (D3DScreenUpdateManager) ScreenUpdateManager.getInstance();
      mgr.runUpdateNow();
    }
  }