asynchronous - Java AWT drawImage race condition - how to use synchronized to avoid it -


after many hours of debugging , analysis, have managed isolate cause of race condition. solving matter!

to see race condition in action, recorded video way in debugging process. have since furthered understanding of situation please forgive poor commentary , silly mechanisms implemented part of debugging process.

http://screencast.com/t/atak1novanjr

so, situation: have double buffered implementation of surface (i.e. java.awt.frame or window) there ongoing thread loops continuously, invoking render process (which performs ui layout , renders backbuffer) , then, post-render, blits rendered area backbuffer screen.

here's pseudo-code version (full version line 824 of surface.java) of double buffered render:

public renderedregions render() {     // pseudo code     renderedregions r = super.render();     if (r==null) // nothing rendered         return     (region in r)         establish max bounds     blit(max bounds)     return r; } 

as awt surface implementation, implements (line 507 in awt.java - link limit :( - use surface.java link, replace core/surface.java plat/awt.java) paint/update overrides blit backbuffer screen:

        public void paint(graphics gr) {             rectangle r = gr.getclipbounds();             refreshfrombackbuffer(r.x - leftinset, r.y - topinset, r.width, r.height);         } 

blitting implemented (line 371 in awt.java) using drawimage() function:

    /** synchronized otherwise possible blit before images have been rendered backbuffer */     public synchronized void blit(pixelbuffer s, int sx, int sy, int dx, int dy, int dx2, int dy2) {         discoverinsets();         try {             window.getgraphics().drawimage(((awtpixelbuffer)s).i,                               dx + leftinset, dy + topinset,     // destination topleft corner                               dx2 + leftinset, dy2 + topinset,   // destination bottomright corner                               sx, sy,                            // source topleft corner                               sx + (dx2 - dx), sy + (dy2 - dy),  // source bottomright corner                               null);         } catch (nullpointerexception npe) { /* fixme: handle gracefully */ }     } 

(warning: start making assumptions!)

the problem here seems drawimage asynchronous , blit refreshbackbuffer() via paint/update called first occurs second.

so... blit synchronized. obvious way of preventing race condition doesn't work. :(

so far have come 2 solutions, neither of them ideal:

  1. re-blit on next render pass
    cons: performance hit, still bit of flicker due when encountering race condition (valid screen -> invalid screen -> valid screen)

  2. do not blit on paint/update, instead set refresh bounds , use bounds on next render pass
    cons: black flicker when screen invalidated , main application thread catching up

here (1) seems lesser of 2 evils. edit: , (2) doesn't work, getting blank screens... (1) works fine masking problem potentially still there.

what i'm hoping for, , seem unable conjure due weak understanding of synchronized , how use it, locking mechanism somehow accounts asynchronous nature of drawimage().

or perhaps use imageobserver?

note due nature of application (vexi, interested, website out of date , can use 2 hyperlinks) render thread must outside of paint/update - has single-threaded script model , layout process (a sub-process of render) invokes script.

not sure, happens if blit in awt paint thread?


Comments

Popular posts from this blog

python - Scipy curvefit RuntimeError:Optimal parameters not found: Number of calls to function has reached maxfev = 1000 -

c# - How to add a new treeview at the selected node? -

java - netbeans "Please wait - classpath scanning in progress..." -