We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › how to solve tearing With double-buffering?Vsync
Page Index Toggle Pages: 1
how to solve tearing? With double-buffering?Vsync? (Read 3128 times)
how to solve tearing? With double-buffering?Vsync?
Jun 6th, 2008, 12:54am
 
Hi all,

I have a horizontal strip of image tiles that I need to make scroll horizontally. Problem is, I get tearing (top of image is one frame behind bottom of image).

I understand that double-buffering will solve this problem. Is this what I want to do? How do I do it? Specifically, do I create a PGraphics buf, then copy pixels from buf to my PApplet first in my draw loop? Or is buf a different type? Do I use get()?

Thanks in advance for any help. I've never worked with double-buffering before....

Pseudo-code follows for my program

Code:

PImage[] images;
Tile[] tile;
long startTime;
float msMap = 0.1;
int numImages = 40;
int w = 40;

void setup() {
 size(1280, 720);

 images = new PImage[numImages];
 tile = new Tile[numImages];

 for (int i = 0; i < numImages; i++) {
   // this is memory-intensive, but allows high framerate
   images[i] = loadImage(i + ".png");

   // in the real app, the widths vary and are read from XML...
   int left = i * w;
   int right = (i+1) * w;
   tile[i] = new Tile(left, right);
 }

 startTime = System.currentTimeMillis();
}

void draw() {
 background(255);
 long et = System.currentTimeMillis() - startTime;
 
 int offset = (int) (et * msMap - width);
 translate(-offset, 0);

 for (int i = 0; i < tile.length; i++) {
   Tile t = tile[i];

   if (t.left <= width + offset && t.right >= offset) {
     image(images[i], t.left, 0);
   }
   // free up memory to load more images via image(...)
   if (t.right < offset) {
     images[i] = null;
   }
 }
}

class Tile {
 int left;
 int right;

 public Tile(int left, int right) {
   this.left = left;
   this.right = right;
 }
}


As a final point, I understand this has something to do with vsync. TomC mentioned something in another post about disabling vsync on the graphics card -- not sure how to do that, I am running Mac OS X 10.5.3 on a Core 2 Duo with NVIDIA 8600M GT 256mb....a cursory search did not turn up any control panel that would let me do this.
Re: how to solve tearing? With double-buffering?Vs
Reply #1 - Jun 6th, 2008, 1:20am
 
Processing is double-buffered by default. If you're seeing tearing, then something weird is going on.
Re: how to solve tearing? With double-buffering?Vs
Reply #2 - Jun 6th, 2008, 1:24am
 
just lower your framerate .. should go away.

F
Re: how to solve tearing? With double-buffering?Vs
Reply #3 - Jun 6th, 2008, 5:57pm
 
Thanks for the responses.

@JohnG: I looked at the code for PApplet, and it is indeed double-buffered. That answers a lot of my questions.

@fjen: Unfortunately, this didn't work. The animation can run at 60fps, but even at 1fps I get tearing.

I should clarify and say that on most of the frames I do not get tearing (but I get it on some).
I think my problem is that the canvas is so large, at 1280 x 720 (the resolution of the projector I will be using). I would think that the problem is that blitting the image takes too long, and occasionally gets interrupted to read the image. Except that paint() is synchronized. I did try making my draw routine synchronized, no help.

I am going to do some additional research, and since the code is so simple, I will probably implement in Java without Processing. I think that I want to try using BufferStrategy, which apparently blits or flips the buffer right after vsync. There are some articles out there on the web. When I get something that solves my issue I will post in this thread.

Also, I should say that I have very sudden color transitions (from bright red to white, say) and I get choppiness. I am going to try motion blur.


Re: how to solve tearing? With double-buffering?Vs
Reply #4 - Jun 8th, 2008, 2:42pm
 
I have done some more research on BufferStrategy / page flipping and came up with the following:

1) only Java 1.4+
2) on most (all?) graphics cards, page flipping will be enabled only in fullscreen mode.

I dug up an item in core/todo.txt that mentions implementing BufferStrategy in the "Bagel" renderer:

http://dev.processing.org/source/index.cgi/*checkout*/trunk/processing/core/todo.txt?rev=4052

This pointed me to

http://processing.org/discourse/yabb/YaBB.cgi?board=Programs;action=display;num=1081335361;start=15

There's a little discussion of BufferStrategy further on in the thread.

There's also the interesting question of why Google is not indexing the alpha board and the svn repository -- but that's for another thread. It would have made my research easier if these were indexed.

Now if I can just find some time to try out BufferStrategy...
[SOLVED] tearing issue
Reply #5 - Jun 11th, 2008, 4:52pm
 
I got it working. Right now it is a class that extends PApplet. I'd like to package it as another renderer, which should be possible. If I do that I'll post it to the libraries category. Here's a description

Q: What does it do?
A: Solves issue of tearing in certain animations.

Q: How does it do it?
A: Uses BufferStrategy, which aligns buffer flips to vsync. This is an active rendering strategy (where the program pushes data to the graphics system) rather than a passive rendering system (where the graphics system issues requests and pulls data from the program -- done in java with paint()/update()).

For more info on active and passive rendering and the "fullscreen exclusive mode API": http://java.sun.com/docs/books/tutorial/extra/fullscreen/index.html


Re: how to solve tearing? With double-buffering?Vsync?
Reply #6 - Mar 29th, 2010, 2:12pm
 
Hey chaz, I seem to be having similar issues. Is there any way I could get more details on how you solved this?
Re: how to solve tearing? With double-buffering?Vsync?
Reply #7 - Mar 29th, 2010, 2:52pm
 
I had a problem with this too... here's a sound-reactive program I wrote... it was having problems with tearing. I found something in a forum thread, somewhere.... that allowed me to turn on vsync which fixed the problem. I've posted the whole program but you can see the vsync bit at the start and in setup. I hope this helps.

[EDIT-If you want to see this program working you need a working microphone which is successfully detected by Minim. Try turning off the openGL stuff to see the horrible tearing]

Code:
import ddf.minim.analysis.*;
import ddf.minim.*;
import processing.opengl.*;
import javax.media.opengl.GL;
Minim minim;
AudioInput in;
FFT fft;
//PrintWriter output;
float[] bands;
float amplitude=0;
float h, s, b; //hue saturation, brightness
PGraphicsOpenGL pgl; //need to use this to stop screen tearing
GL gl;


void setup()
{
 size(640, 480, OPENGL);
 pgl = (PGraphicsOpenGL) g; //processing graphics object
 gl = pgl.beginGL(); //begin opengl
 gl.setSwapInterval(1); //set vertical sync on
 pgl.endGL(); //end opengl
 background(0);
 frameRate(30);
 //output= createWriter("sounddata.txt");
 bands = new float[10];
 minim = new Minim(this);
 in = minim.getLineIn(Minim.STEREO, 512);
 fft= new FFT(in.bufferSize(), in.sampleRate());
 fft.logAverages(22, 1);
 colorMode(HSB, 255, 255, 255);
}


void draw()
{
 amplitude=0;
 fft.forward(in.mix);
  for(int i=0; i<fft.avgSize(); i++)
  {
bands[i]=fft.getAvg(i);
  }
 
  s = (bands[0] + bands[1] + bands[2] + bands[3])/4;
  b =  (bands[4] + bands[5] + bands[6])/3;
  h=  (bands[7] + bands[8] + bands[9])/3;
 
  for(int i=0; i<10; i++)
  {
    amplitude+= bands[i];
  }
 
  s= map(s, 0.88, 1, 0, 255);
  b = map(b, 0.026, 1, 0, 255);
  h= map(h, 0.011, 0.5, 0, 255);
 
  color c = color(h, s, b);
  loadPixels();
  for (int i=0; i< pixels.length; i++)
  {
    pixels[i]=c;
  }
  updatePixels();
}
Page Index Toggle Pages: 1