I'm trying to solve this problem but so far the only thing i've found is disabling the hardware acceleration. It actually works but it makes the scroll laggy is there a way to solve this problem but keeping the hardware acceleration on?
So the only solution was using software rendering and optimizing the code so it can scroll smoothly. In my case I was drawing the curve in the onDraw method and it was called everytime I scrolled redrawing the curve several times per second, this was fast using hardware acceleration but really slow on software. Now I draw the curve in a bitmap only once and set the bitmap as background of the view redrawing only the pointer onscroll making the scroll smooth even without software acceleration. I hope this can help anybody with the a similar problem!
Related
I know this is quite the same question as partial-invalidation-in-custom-android-view-with-hardware-acceleration but I thought I will explain my problem more detailled and hope someone will have an answer on how to solve the problem.
I wrote a simple TicTacToe app which was working fine on the emulator. But wasn't working on the device since I found out it was working as expected on the device when I disabled hardware acceleration.
All the fields are drawn with Canvas.drawBitmap(), also the "empty" fields with an empty white image. The lines are drawn with Canvas.drawLine()
I'm using partial invalidation with invalidate(Rect) because I want to redraw only the area which was choosen to set a cross/circle with the according image using again Canvas.drawBitmap(). But then the whole area is invalidated, means I see the whole area/screen is gray (the white images and lines disappeared) and only the image for the cross/circle is set in the choosen area.
When I print out the invalidated field rect with Canvas.getClipBounds() in the method onDraw(), with hardware acceleration it is the whole area (example "0,0,320,407") and without hardware acceleration the same rect which I invalidated with invalidate(Rect) (e.g. "106,135,106,135").
At the moment as workaround I redraw all the fields whith the according image and lines. How can I prevent to have the whole area invalidated with hardware acceleration?
If this matters: I'm using Android version 4.1.2 on Samsung Galaxy Young Duos S6312.
Regards
Sandro
I have post my answer in your given link. To understand the problem , you should know the difference between software rendering and hardware rendering. That's really a big topic which I won't cover here. I think the best approach is to read the source code(I did the same thing a few days ago). The key question is "what is DisplayList and when it is used"
. Repeat my answer here, the Canvas in onDraw is simply used to rebuild the DisplayList. That doesn't mean everything in your View will be redrawn.
I have a GLSurfaceView with a renderer assigned to it. On this view, I draw images which seem to be offset to the left compared to where I have requested that they be drawn on it. This problem has only arisen since I switched from Canvas-based rendering, which rendered the images in their correct positions, to OpenGL 1.0 rendering, which doesn't.
I have read through my code and have found absolutely nothing that could be causing this. What frustrates me is that I know there is nothing wrong with the positions I set using my code, but the problem still persists.
Now, here's the best part of it all. When I pause the application by pressing the home button, and then restart the application through the task manager, the positions are fixed and are exactly how they should be, which leads me to believe that the problem isn't with the positions I set using my code, but how I've set up my surface view. I've checked the dimensions in the onSurfaceChanged() parameters only to find that they are always as they should be, which leaves me even more confused.
Does anyone have any idea what could be causing this problem?
After much digging through my project, I discovered I was setting positions based on the dimensions of the GLSurfaceView before onSurfaceChanged had been called in the onSurfaceCreated method, therefore the width/height of the view at this point was 0 which affected the positions of my objects on the screen.
I feel really stupid now.
I know this question has been asked to death, but I'm somewhat confused about the answers I've been seeing. So I want to resize a bitmap I am displaying on the screen in my android app. I need to be able to resize it efficiently, in real time. It is expected for the user to be constantly resizing / panning around the image, so I want to do this as efficiently as possible.
So far, I've only seen Bitmap.createScaledBitmap(...) which seems like its completely rebuilding the bitmap. It gets a bit of lag when the user is performing pinch and zoom (many resizes in a row).
Whats weird is that when I tried using canvas.scale(...), there was no lag in zooming the image. The only problem with this is that it resizes the coordinates as well, making it impossible to use in this application. Is there something similar to canvas.scale() for Bitmaps, that just scale the image without reloading it, similar to canvas.scale()?
You can find all the Canvas methods here.
What you are after is probably a combination of Canvas.scale(...) and the Canvas.save()/Canvas.restore() methods to reset the coordinates after drawing.
If this is not what you are looking for, another solution might be to get the current transformation matrix and apply to your coordinates to get the 'currently active' coordinates.
I have a big custom View, and I draw a lot of rich text on it, many fonts, multiple colors and font sizes. I already optimized this drawing as much as possible. The redraw takes about 300ms.
This 300ms is OK for one time call, but since my View is bigger than the screen, it is inserted into the ScrollView, and now once the user scrolls with the finger, onDraw() is called repeatedly. Which gives very sloppy scrolling.
The same application was previously written for iOS, and iOS will not call onDraw (I think it is called drawRect() in iOS world), and all the drawn image is stored in some sort of buffer, so scrolling actually is very fast and ultra smooth, probably hardware accelerated.
So is there a way to achieve something like "No onDraw" smooth scrolling? I was thinking about drawing onto bitmap, and then blitting the bitmap during the scroll phases. But will it be any faster than drawing text? Are bitmaps HW accelerated on Android? What is the best approach to this kind of problem?
Thank you
Make the entire drawing into a Bitmap object using associated Canvas and in onDraw just flush this Bitmap. When you data changes, redraw everything into Bitmap.
We are trying to create a text animation like Transition and Zoom on the Video.
We are not able to get Smooth transition and the effect is so jerky. Then we understood sub pixel rendering is not possible in android.
What alternatives can we think of? Can we solve this problem in OpenGL?
Ok... I would like to add more to my question....We are actually trying to implement text animations on top of a video which is played by a native player on a surface view.
We tried to achieve the text animations using the android Canvas APIs to scale, translate etc and draw the text. This works but the output is not so smooth. We have verified that its not a performance issue. Even if we refresh the frames at more than 30fps, the
jerkiness is seen.
Then, we tried to use android Views to get these animations and observed that the animations are buttery smooth when Hardware acceleration is turned on. But even the android View system animation fails to give good quality scale animations when hardware acceleration is turned OFF.
This again is not a performance issue since we have tried to dump each frame into a bitmap and checked each frame on PC.
So, it seems that SKIA graphics library used to draw on Canvas when hardware acceleration is turned off, is not capable of sub pixel rendering or something of that sort. For example, when i am running a slow scale animation (a scale of about 0.15 in about 6 seconds), the scale updates happen by 1 pixel in around 3 frames.
But if the same animation is run on a hardware accelerated view, each frames updates a fraction of a pixel and the scale animation looks
very smooth.
I can sure use the view animations while previewing. But I need to get these animation buffers and encode them along with the video. Any inputs on getting these buffers, with hardware acceleration turned ON would help. I have tried Drawing cache, but that seems to be drawn using software rendering pipeline and not hardware.
Smooth transistions and jerky animations have nothing to do with subpixel rendering.
The problem sounds like you're not correctly timing your rendering function. Do not use a interval timer to trigger rendering of a frame. You should put the rendering and animation into your programs event loop idle handler and measure the time it takes to render a frame. Then advance the animation by that time.