/**
   * Disposes the native resources associated with the given D3DSurfaceData (referenced by the pData
   * parameter). This method is invoked from the native Dispose() method from the Disposer thread
   * when the Java-level D3DSurfaceData object is about to go away.
   */
  static void dispose(long pData) {
    D3DRenderQueue rq = D3DRenderQueue.getInstance();
    rq.lock();
    try {
      RenderBuffer buf = rq.getBuffer();
      rq.ensureCapacityAndAlignment(12, 4);
      buf.putInt(DISPOSE_SURFACE);
      buf.putLong(pData);

      // this call is expected to complete synchronously, so flush now
      rq.flushNow();
    } finally {
      rq.unlock();
    }
  }
  @Override
  public void flush() {
    D3DRenderQueue rq = D3DRenderQueue.getInstance();
    rq.lock();
    try {
      RenderBuffer buf = rq.getBuffer();
      rq.ensureCapacityAndAlignment(12, 4);
      buf.putInt(FLUSH_SURFACE);
      buf.putLong(getNativeOps());

      // this call is expected to complete synchronously, so flush now
      rq.flushNow();
    } finally {
      rq.unlock();
    }
  }
 static void swapBuffers(
     D3DSurfaceData sd, final int x1, final int y1, final int x2, final int y2) {
   long pData = sd.getNativeOps();
   D3DRenderQueue rq = D3DRenderQueue.getInstance();
   // swapBuffers can be called from the toolkit thread by swing, we
   // should detect this and prevent the deadlocks
   if (rq.isRenderQueueThread()) {
     if (!rq.tryLock()) {
       // if we could not obtain the lock, repaint the area
       // that was supposed to be swapped, and no-op this swap
       final Component target = (Component) sd.getPeer().getTarget();
       SunToolkit.executeOnEventHandlerThread(
           target,
           new Runnable() {
             public void run() {
               target.repaint(x1, y1, x2, y2);
             }
           });
       return;
     }
   } else {
     rq.lock();
   }
   try {
     RenderBuffer buf = rq.getBuffer();
     rq.ensureCapacityAndAlignment(28, 4);
     buf.putInt(SWAP_BUFFERS);
     buf.putLong(pData);
     buf.putInt(x1);
     buf.putInt(y1);
     buf.putInt(x2);
     buf.putInt(y2);
     rq.flushNow();
   } finally {
     rq.unlock();
   }
 }