/** * Creates a graphics object for the passed in surface data. If * the surface is lost, it is restored. * If the surface wasn't lost or the restoration was successful * the surface is added to the list of maintained surfaces * (if it hasn't been already). * * If the updater thread hasn't been created yet , it will be created and * started. * * @param sd surface data for which to create SunGraphics2D * @param peer peer associated with the surface data * @param fgColor fg color to be used in graphics * @param bgColor bg color to be used in graphics * @param font font to be used in graphics * @return a SunGraphics2D object for the surface (or for temp GDI * surface data) */ @Override public Graphics2D createGraphics(SurfaceData sd, WComponentPeer peer, Color fgColor, Color bgColor, Font font) { if (!done && sd instanceof D3DWindowSurfaceData) { D3DWindowSurfaceData d3dw = (D3DWindowSurfaceData)sd; if (!d3dw.isSurfaceLost() || validate(d3dw)) { trackScreenSurface(d3dw); return new SunGraphics2D(sd, fgColor, bgColor, font); } // could not restore the d3dw surface, use the cached gdi surface // instead for this graphics object; note that we do not track // this new gdi surface, it is only used for this graphics // object sd = getGdiSurface(d3dw); } return super.createGraphics(sd, peer, fgColor, bgColor, font); }
/** * Creates a SurfaceData object representing the back buffer of a * double-buffered on-screen Window. */ public static D3DSurfaceData createData(WComponentPeer peer, Image image) { D3DGraphicsConfig gc = getGC(peer); if (gc == null || !peer.isAccelCapable()) { return null; } BufferCapabilities caps = peer.getBackBufferCaps(); VSyncType vSyncType = VSYNC_DEFAULT; if (caps instanceof ExtendedBufferCapabilities) { vSyncType = ((ExtendedBufferCapabilities)caps).getVSync(); } Rectangle r = peer.getBounds(); BufferCapabilities.FlipContents flip = caps.getFlipContents(); int swapEffect; if (flip == FlipContents.COPIED) { swapEffect = SWAP_COPY; } else if (flip == FlipContents.PRIOR) { swapEffect = SWAP_FLIP; } else { // flip == FlipContents.UNDEFINED || .BACKGROUND swapEffect = SWAP_DISCARD; } return new D3DSurfaceData(peer, gc, r.width, r.height, image, peer.getColorModel(), peer.getBackBuffersNum(), swapEffect, vSyncType, FLIP_BACKBUFFER); }
/** * Creates a SurfaceData object representing the back buffer of a * double-buffered on-screen Window. */ public static WGLOffScreenSurfaceData createData(WComponentPeer peer, Image image, int type) { // the OGL pipeline can render directly to the screen and interfere // with layered windows, which is why we don't allow accelerated // surfaces in this case if (!peer.isAccelCapable() || !SunToolkit.isContainingTopLevelOpaque((Component)peer.getTarget())) { return null; } WGLGraphicsConfig gc = getGC(peer); Rectangle r = peer.getBounds(); if (type == FLIP_BACKBUFFER) { return new WGLOffScreenSurfaceData(peer, gc, r.width, r.height, image, peer.getColorModel(), type); } else { return new WGLVSyncOffScreenSurfaceData(peer, gc, r.width, r.height, image, peer.getColorModel(), type); } }
/** * Creates a new SurfaceData that will be associated with the given * WComponentPeer. D3D9 doesn't allow rendering to the screen, * so a GDI surface will be returned. */ @Override public SurfaceData createSurfaceData(WComponentPeer peer, int numBackBuffers) { return super.createSurfaceData(peer, numBackBuffers); }
/** * Creates a D3D-based backbuffer for the given peer and returns the * image wrapper. */ @Override public VolatileImage createBackBuffer(WComponentPeer peer) { Component target = (Component)peer.getTarget(); // it is possible for the component to have size 0x0, adjust it to // be at least 1x1 to avoid IAE int w = Math.max(1, target.getWidth()); int h = Math.max(1, target.getHeight()); return new SunVolatileImage(target, w, h, Boolean.TRUE); }
/** * Determines if we can use a d3d surface for onscreen rendering for this * peer. * We only create onscreen d3d surfaces if the following conditions are met: * - d3d is enabled on this device and onscreen emulation is enabled * - window is big enough to bother (either dimension > MIN_WIN_SIZE) * - this heavyweight doesn't have a BufferStrategy * - if we are in full-screen mode then it must be the peer of the * full-screen window (since there could be only one SwapChain in fs) * and it must not have any heavyweight children * (as Present() doesn't respect component clipping in fullscreen mode) * - it's one of the classes likely to have custom rendering worth * accelerating * * @returns true if we can use a d3d surface for this peer's onscreen * rendering */ public static boolean canUseD3DOnScreen(final WComponentPeer peer, final Win32GraphicsConfig gc, final int bbNum) { if (!(gc instanceof D3DGraphicsConfig)) { return false; } D3DGraphicsConfig d3dgc = (D3DGraphicsConfig)gc; D3DGraphicsDevice d3dgd = d3dgc.getD3DDevice(); String peerName = peer.getClass().getName(); Rectangle r = peer.getBounds(); Component target = (Component)peer.getTarget(); Window fsw = d3dgd.getFullScreenWindow(); return WindowsFlags.isD3DOnScreenEnabled() && d3dgd.isD3DEnabledOnDevice() && peer.isAccelCapable() && (r.width > MIN_WIN_SIZE || r.height > MIN_WIN_SIZE) && bbNum == 0 && (fsw == null || (fsw == target && !hasHWChildren(target))) && (peerName.equals("sun.awt.windows.WCanvasPeer") || peerName.equals("sun.awt.windows.WDialogPeer") || peerName.equals("sun.awt.windows.WPanelPeer") || peerName.equals("sun.awt.windows.WWindowPeer") || peerName.equals("sun.awt.windows.WFramePeer") || peerName.equals("sun.awt.windows.WEmbeddedFramePeer")); }
/** * Posts a repaint event for the peer's target to the EDT * @param peer for which target's the repaint should be issued */ private void repaintPeerTarget(WComponentPeer peer) { Component target = (Component)peer.getTarget(); Rectangle bounds = AWTAccessor.getComponentAccessor().getBounds(target); // the system-level painting operations should call the handlePaint() // method of the WComponentPeer class to repaint the component; // calling repaint() forces AWT to make call to update() peer.handlePaint(0, 0, bounds.width, bounds.height); }
@Override public SurfaceData getReplacementScreenSurface(WComponentPeer peer, SurfaceData sd) { SurfaceData newSurface = super.getReplacementScreenSurface(peer, sd); // if some outstanding graphics context wants to get a replacement we // need to make sure that the new surface (if it is accelerated) is // being tracked trackScreenSurface(newSurface); return newSurface; }
/** * Returns true if the component has heavyweight children. * * @param comp component to check for hw children * @return true if Component has heavyweight children */ private static boolean hasHWChildren(Component comp) { if (comp instanceof Container) { for (Component c : ((Container)comp).getComponents()) { if (c.getPeer() instanceof WComponentPeer || hasHWChildren(c)) { return true; } } } return false; }
protected D3DSurfaceData(WComponentPeer peer, D3DGraphicsConfig gc, int width, int height, Image image, ColorModel cm, int numBackBuffers, int swapEffect, VSyncType vSyncType, int type) { super(getCustomSurfaceType(type), cm); this.graphicsDevice = gc.getD3DDevice(); this.peer = peer; this.type = type; this.width = width; this.height = height; this.offscreenImage = image; this.backBuffersNum = numBackBuffers; this.swapEffect = swapEffect; this.syncType = vSyncType; initOps(graphicsDevice.getScreen(), width, height); if (type == WINDOW) { // we put the surface into the "lost" // state; it will be restored by the D3DScreenUpdateManager // prior to rendering to it for the first time. This is done // so that vram is not wasted for surfaces never rendered to setSurfaceLost(true); } else { initSurface(); } setBlitProxyKey(gc.getProxyKey()); }
private static D3DGraphicsConfig getGC(WComponentPeer peer) { GraphicsConfiguration gc; if (peer != null) { gc = peer.getGraphicsConfiguration(); } else { GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = env.getDefaultScreenDevice(); gc = gd.getDefaultConfiguration(); } return (gc instanceof D3DGraphicsConfig) ? (D3DGraphicsConfig)gc : null; }
public D3DWindowSurfaceData(WComponentPeer peer, D3DGraphicsConfig gc) { super(peer, gc, peer.getBounds().width, peer.getBounds().height, null, peer.getColorModel(), 1, SWAP_COPY, VSYNC_DEFAULT, WINDOW); dirtyTracker = getStateTracker(); }
/** * If the destination surface's peer can potentially handle accelerated * on-screen rendering then it is likely that the condition which resulted * in VI to Screen operation is temporary, so this method sets the * restore countdown in hope that the on-screen accelerated rendering will * resume. In the meantime the backup surface of the VISM will be used. * * The countdown is needed because otherwise we may never break out * of "do { vi.validate()..} while(vi.lost)" loop since validate() could * restore the source surface every time and it will get lost again on the * next copy attempt, and we would never get a chance to use the backup * surface. By using the countdown we allow the backup surface to be used * while the screen surface gets sorted out, or if it for some reason can * never be restored. * * If the destination surface's peer could never do accelerated onscreen * rendering then the acceleration for the SurfaceManager associated with * the source surface is disabled forever. */ static void handleVItoScreenOp(SurfaceData src, SurfaceData dst) { if (src instanceof D3DSurfaceData && dst instanceof GDIWindowSurfaceData) { D3DSurfaceData d3dsd = (D3DSurfaceData)src; SurfaceManager mgr = SurfaceManager.getManager((Image)d3dsd.getDestination()); if (mgr instanceof D3DVolatileSurfaceManager) { D3DVolatileSurfaceManager vsm = (D3DVolatileSurfaceManager)mgr; if (vsm != null) { d3dsd.setSurfaceLost(true); GDIWindowSurfaceData wsd = (GDIWindowSurfaceData)dst; WComponentPeer p = wsd.getPeer(); if (D3DScreenUpdateManager.canUseD3DOnScreen(p, (Win32GraphicsConfig)p.getGraphicsConfiguration(), p.getBackBuffersNum())) { // 10 is only chosen to be greater than the number of // times a sane person would call validate() inside // a validation loop, and to reduce thrashing between // accelerated and backup surfaces vsm.setRestoreCountdown(10); } else { vsm.setAccelerationEnabled(false); } } } } }
protected WGLSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, ColorModel cm, int type) { super(gc, cm, type); this.peer = peer; this.graphicsConfig = gc; Win32GraphicsDevice device = gc.getDevice(); this.scaleX = type == TEXTURE ? 1 : device.getDefaultScaleX(); this.scaleY = type == TEXTURE ? 1 : device.getDefaultScaleY(); long pConfigInfo = gc.getNativeConfigInfo(); long hwnd = peer != null ? peer.getHWnd() : 0L; initOps(pConfigInfo, peer, hwnd); }
private GDIWindowSurfaceData(WComponentPeer peer, SurfaceType sType) { super(sType, peer.getDeviceColorModel()); ColorModel cm = peer.getDeviceColorModel(); this.peer = peer; int rMask = 0, gMask = 0, bMask = 0; int depth; switch (cm.getPixelSize()) { case 32: case 24: if (cm instanceof DirectColorModel) { depth = 32; } else { depth = 24; } break; default: depth = cm.getPixelSize(); } if (cm instanceof DirectColorModel) { DirectColorModel dcm = (DirectColorModel)cm; rMask = dcm.getRedMask(); gMask = dcm.getGreenMask(); bMask = dcm.getBlueMask(); } this.graphicsConfig = (Win32GraphicsConfig) peer.getGraphicsConfiguration(); this.solidloops = graphicsConfig.getSolidLoops(sType); Win32GraphicsDevice gd = (Win32GraphicsDevice)graphicsConfig.getDevice(); initOps(peer, depth, rMask, gMask, bMask, gd.getScreen()); setBlitProxyKey(graphicsConfig.getProxyKey()); }
/** * Creates a new SurfaceData that will be associated with the given * WComponentPeer. */ @Override public SurfaceData createSurfaceData(WComponentPeer peer, int numBackBuffers) { SurfaceData sd = WGLSurfaceData.createData(peer); if (sd == null) { sd = GDIWindowSurfaceData.createData(peer); } return sd; }
/** * Creates a WGL-based backbuffer for the given peer and returns the * image wrapper. */ @Override public VolatileImage createBackBuffer(WComponentPeer peer) { Component target = (Component)peer.getTarget(); return new SunVolatileImage(target, target.getWidth(), target.getHeight(), Boolean.TRUE); }
protected WGLSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, ColorModel cm, int type) { super(gc, cm, type); this.peer = peer; this.graphicsConfig = gc; long pConfigInfo = gc.getNativeConfigInfo(); long hwnd = peer != null ? peer.getHWnd() : 0L; initOps(pConfigInfo, peer, hwnd); }
public WGLOffScreenSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, int width, int height, Image image, ColorModel cm, int type) { super(peer, gc, cm, type); this.width = (int) Math.ceil(width * scaleX); this.height = (int) Math.ceil(height * scaleY); offscreenImage = image; initSurface(this.width, this.height); }
public static WGLGraphicsConfig getGC(WComponentPeer peer) { if (peer != null) { return (WGLGraphicsConfig)peer.getGraphicsConfiguration(); } else { // REMIND: this should rarely (never?) happen, but what if // default config is not WGL? GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = env.getDefaultScreenDevice(); return (WGLGraphicsConfig)gd.getDefaultConfiguration(); } }
public WGLVSyncOffScreenSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, int width, int height, Image image, ColorModel cm, int type) { super(peer, gc, width, height, image, cm, type); flipSurface = WGLSurfaceData.createData(peer, image, FLIP_BACKBUFFER); }
public WGLOffScreenSurfaceData(WComponentPeer peer, WGLGraphicsConfig gc, int width, int height, Image image, ColorModel cm, int type) { super(peer, gc, cm, type); this.width = width; this.height = height; offscreenImage = image; initSurface(width, height); }