@Override
    void restoreSurface() {
      if (!peer.isAccelCapable()) {
        throw new InvalidPipeException("Onscreen acceleration " + "disabled for this surface");
      }
      Window fsw = graphicsDevice.getFullScreenWindow();
      if (fsw != null && fsw != peer.getTarget()) {
        throw new InvalidPipeException(
            "Can't restore onscreen surface" + " when in full-screen mode");
      }
      super.restoreSurface();
      // if initialization was unsuccessful, an IPE will be thrown
      // and the surface will remain lost
      setSurfaceLost(false);

      // This is to make sure the render target is reset after this
      // surface is restored. The reason for this is that sometimes this
      // surface can be restored from multiple threads (the screen update
      // manager's thread and app's rendering thread) at the same time,
      // and when that happens the second restoration will create the
      // native resource which will not be set as render target because
      // the BufferedContext's validate method will think that since the
      // surface data object didn't change then the current render target
      // is correct and no rendering will appear on the screen.
      D3DRenderQueue rq = D3DRenderQueue.getInstance();
      rq.lock();
      try {
        getContext().invalidateContext();
      } 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();
   }
 }