Surfaceview troubles (2)-partial refresh and first and second frame Conjecture

Source: Internet
Author: User
Tags clear screen

Previous Article "surfaceview troubles (1)-dual cache and screen clearing
"Provides a solution: Clear the screen and re-draw all the images each time. Here there are two meanings: Clear the screen to clear the last residual, there will be no overlap; all re-painting, information will not be incomplete because of the clear screen. This method is very effective, regardless of the underlying principle of surfaceview's double buffer display (FLIP), there will be no question about the "first or second frame conjecture" mentioned below.

Although the method is effective, the efficiency of this method is very poor when only a small part of the area is painted at a time and the areas of the painting do not overlap; in this case, we hope to continue painting on the basis of the original screen. Below is the test code. Most of the Code is the same as in the previous article, except for the run () method in mytimertask:

Main. xml

<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> Android: Orientation = "vertical" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> <COM. tutor. surface. mysurfaceview <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent" <br/> </linearlayout>

Mysurfaceview. Java

Package COM. tutor. surface; <br/> Import Java. util. timer; <br/> Import android. content. context; <br/> Import android. util. attributeset; <br/> Import android. view. surfaceholder; <br/> Import android. view. surfaceview; <br/> public class mysurfaceview extends surfaceview implements surfaceholder. callback {<br/> private timer = NULL; <br/> private mytimertask task = NULL; <br/> Public mysurfaceview (contex T context, attributeset attrs) {<br/> super (context, attrs); <br/> surfaceholder holder = getholder (); <br/> holder. addcallback (this); <br/>}< br/> @ override <br/> Public void surfacechanged (surfaceholder holder, int format, int width, <br/> int height) {<br/> // todo auto-generated method stub <br/>}< br/> @ override <br/> Public void surfacecreated (surfaceholder holder) {<br/> // todo auto-generated Method stub <br/> timer = new timer (); <br/> task = new mytimertask (holder); <br/> // There is a comment-out code, the following shows the difference between the sentence and the sentence. <br/> // task. cleardraw (); <br/> timer. schedule (task, 500,100 0); <br/>}< br/> @ override <br/> Public void surfacedestroyed (surfaceholder holder) {<br/> // todo auto-generated method stub <br/> If (timer! = NULL) {<br/> timer. cancel (); <br/> timer = NULL; <br/>}< br/> task = NULL; <br/>}</P> <p >}< br/>

Mytimertask. Java

Package COM. tutor. surface; <br/> Import Java. util. timertask; <br/> Import android. graphics. canvas; <br/> Import android. graphics. color; <br/> Import android. graphics. paint; <br/> Import android. graphics. rect; <br/> Import android. view. surfaceholder; <br/> public class mytimertask extends timertask {<br/> private surfaceholder holder = NULL; </P> <p> private int left = 50; <br/> private int Top = 5; <br/> priva Te int width = 20; </P> <p> private paint = NULL; <br/> Boolean isrunning = true; <br/> private int COUNT = 0; </P> <p> Public mytimertask (surfaceholder _ holder) {<br/> holder = _ holder; <br/> paint = new paint (); <br/> paint. setcolor (color. white); <br/>}</P> <p> @ override <br/> Public void run () {<br/> // todo auto-generated method stub <br/> If (top> 400) // test the program, when the ordinate value exceeds 400, no painting is made. <br/> return; </P> <p> switch (Count % 5) {<br/> case 0: <br/> paint. setcolor (color. blue); <br/> break; <br/> case 1: <br/> paint. setcolor (color. white); <br/> break; <br/> case 2: <br/> paint. setcolor (color. yellow); <br/> break; <br/> case 3: <br/> paint. setcolor (color. red); <br/> break; <br/> case 4: <br/> paint. setcolor (color. green); <br/> break; <br/>}</P> <p> canvas = NULL; <br/> try {<br/> rect rectdirty = new rect (left, top, left + wid Th, top + width); <br/> rect rectangle = new rect (left, top, left + width, top + width ); </P> <p> canvas = holder. lockcanvas (rectdirty); <br/> canvas. drawrect (rectangle, paint); <br/> top + = 25; <br/> If (top> 400) {<br/> isrunning = false; <br/>}< br/>} catch (exception e) {<br/> // todo: handle exception <br/>}finally {<br/> If (canvas! = NULL) {<br/> holder. unlockcanvasandpost (canvas); <br/>}< br/> count ++; <br/>}</P> <p> Public void cleardraw () {<br/> canvas = NULL; <br/> try {<br/> canvas = holder. lockcanvas (null); <br/> canvas. drawcolor (color. black); <br/>} catch (exception e) {<br/> // todo: handle exception <br/>} finally {<br/> If (canvas! = NULL) {<br/> holder. unlockcanvasandpost (canvas); <br/>}< br/>

 

The result is as follows:

(1) In mysurfaceview, if you do not call clear screen before timer starts (that is, comment out task. cleardraw (), the result is:

(2) If the first screen is added, the result is as follows:

 

Obviously, the first result was missing a blue block at the beginning, which indicates that some of the information to be drawn was washed out (or overwritten ); the second result is what we want.

(1) From the code, we can see that the position of the rectangle is different each time, and the position of each painting does not overlap with the area previously drawn, you can use the incremental method to draw images (that is, to save the original image), so that you do not need to redraw all the images each time, and the efficiency is improved.

(2) there seems to be no first or second frame in the code. In fact, in the first attempt, the screen was not cleared before the timer was started; instead, the run () in mytimertask () use COUNT = 0 and count = 1 to test the first and second frames. The surfaceview principle is implemented by calling the underlying library using JNI (a few lines of Java code are used), which means you want to understand the principle of surfaceview, I have to go deep into non-Java code (I don't have any good solutions at the moment, please let me know if you have any ). Therefore, we can only perform a conjecture here.

 

First and second frame conjecture:

Although only a small part of the area is locked each time a canvas is drawn during partial update, I guess the first and second frames are all changed, it is not just a small part of the locked area. The first frame is called for the first time mytimertask's run () method is called to draw a panel. Here, it is displayed alternately according to the surfaceview's double buffering principle, switch the back buffer of the entire screen size to the Front (and draw the first blue block). At this time, the front buffer is switched back to the background (the front buffer is black in full screen ); when calling the run () method of mytimertask to draw a panel for the second time, draw a white square in the front buffer and display it (Note: because there is no square before the front buffer, the first blue block is in the back buffer). The blue block is washed out and only the white block is left. Specifically, only the two frames are switched across the entire panel. The space for switching between the front buffer and back buffer is changed to the locked panel area, because the locked panel area is a different small area each time, the dual-buffering alternate only this small area, rather than the entire screen; in addition to the locked area, the content of other areas is retained.

If you clear the screen before timer starts (in fact, to call holder. unlockcanvasandpost (canvas) so that the original back buffer is switched first), and then draw the image on this basis, there is no problem. Therefore, the read method is used in the run () method. The first frame is only post, and the actual content is also drawn from the second frame.

 

The above is just a conjecture. Only those who have a deep understanding of the Code below can know whether it is correct. If you know something about it, elaborate on it. There are two proofs below:

(1) rectdirty of the region locked in mytimertask, if it is directly transferred to the canvas in the following drawing box code. drawrect (rectdirty, paint);, you will find an interesting phenomenon: First, you will see the screen background turns to full blue (not all black), and then the screen background turns to full White, after that, the screen background color will not change (it has always been white), except for the first blue block, the square will be normal. This phenomenon is consistent with the first and second frames of the above conjecture. What is not clear at present is why the entire background color is changed. It is no problem to create a new rect with the same size and starting coordinate for the locked area.

(2) hellogv Daniel wrote an example: http://blog.csdn.net/hellogv/archive/2010/11/03/5985090.aspx, because the previous found this example is part of the refresh, so focus on learning a bit. When I encountered the first or second frame problem, I looked back at this example and thought about why it didn't. In fact, the first and second frames are not painted, but the Panel is directly displayed (unlockcanvasandpost (canvas). I don't know if this is the case, but there are other reasons.

 

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.