First of all, if you want to understand what is happening under the hood, you need to read the Android Graphics graphic project . It's a long time, but if you sincerely want to understand why, this is the place to start.
About TextureView
TextureView works as follows: it has a Surface, which is a queue of buffers with producer-consumer relations. If you use software rendering (Canvas), you block Surface, which gives you a buffer; you rely on him; then you unblock the Surface, which sends the buffer to the consumer. The consumer in this case is in the same process and is called SurfaceTexture or (internally, more aptly) GLConsumer. It converts the buffer to an OpenGL ES texture, which is then displayed in the view.
If you disable hardware acceleration, GLES is disabled, and TextureView cannot do anything. That's why you got nothing when you turned off hardware acceleration. The documentation is very specific: "TextureView can only be used in a hardware accelerated window. When rendering in software, TextureView does not draw anything."
If you specify a dirty rectangle, the software rendering will memcpy the previous contents into the frame after rendering is complete. I donβt think it sets a direct clip, so if you call drawColor (), you fill the whole screen and then reload these pixels. If you are not currently installing a direct clip, you can see some performance benefits from this. (I did not check the code, though.)
A dirty rectangle is an input parameter. You pass in the required address when you call lockCanvas() , and the system is allowed to change it before the call returns. (In practice, the only reason this will be done is if the previous frame or surface size had not been changed, in which case he would expand it to cover the entire screen. I think it would be better processed with more direct βI reject your direct signal.β) You need to update every pixel inside the rectangle that you will return. You are not allowed to change the rectangle that you are trying to do in your example - everything that is in the dirty rectangle after lockCanvas() is done is what you need to draw.
I suspect that improper handling of dirty lines is the source of your flicker. Unfortunately, this is not a simple mistake, since the behavior of the lockCanvas() dirtyRect described only in the Surface class itself .
Surfaces and Buffering
All surfaces are double or triple buffers. There is no way around this - you cannot read and write at the same time, not break. If you need one buffer that you can change and click whenever you want, this buffer will need to be locked, copied and unlocked, which creates kiosks in the composition pipeline. For best throughput and latency, flip buffers are best.
If you want lock-unlock behavior, you can write it yourself (or find a library that does this) and it will be as effective as if the system did this for you (if you want, re good with blit loop). Draw a bitmap on the Canvas and blit screen, or in OpenGL ES FBO and blit buffer. You can find an example of the latter in Grafika's β Record GL Application β Activity, which has a mode that displays once off-screen and then blits twice (once for display, once for video recording).
Higher speed and
There are two main ways to draw pixels on Android: with Canvas or with OpenGL. Mapping the canvas to the surface or bitmap is always done in software, and OpenGL is rendered using the GPU. The only exception is that when rendering a custom view, you can use hardware acceleration, but this does not apply to rendering to a SurfaceView or TextureView.
A drawing or drawing application can either memorize drawing commands or simply throw pixels into the buffer and use this as its memory. The former allows you to βundo" deeper, the latter is much simpler and has higher productivity, as the amount of material for rendering is growing. It looks like you want to do the latter, so mixing from the screen does not make sense.
Most mobile devices have a hardware limit of 4096x4096 or less for GLES textures, so you cannot use a single texture for anything more. You can request a size limit (GL_MAX_TEXTURE_SIZE), but you might be better off with the internal buffer you need and just draw the part that fits the screen. I don't know what the Skia (Canvas) limitation is, but I believe that you can create much larger bitmaps.
Depending on your needs, SurfaceView may be preferable to TextureView, as it avoids the intermediate stage of the GLES texture. Everything that you paint on the surface is directly related to the system builder (SurfaceFlinger). The downside of this approach is that since the Surface user is not in the process, there is no way for the View system to process the output, so Surface is an independent layer. (For a drawing program, this can be useful - the image that is being drawn is on the same level, your user interface is on a separate layer at the top.)
FWIW, I didnβt look at the code, but Dan Sandler Markers application may be worth a peek (source code here ).
Update: corruption has been identified as a bug and fixed in 'L' .