Skip to content

Commit

Permalink
Fix Stack overflow in drawUnderlyingViews: add requirement to use har…
Browse files Browse the repository at this point in the history
…dware accelerated window. Renaming and refactoring
  • Loading branch information
saviukd authored and saviukd committed Sep 1, 2016
1 parent 97d00a3 commit 17172c7
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@
* After that, BlurController blurs this bitmap and draws it on system Canvas.
* Default implementation uses {@link ViewTreeObserver.OnPreDrawListener} to detect when
* blur should be redrawn.
*
* Blur is done in the main thread.
*/
class DefaultBlurController implements BlurController {
private static final String TAG = DefaultBlurController.class.getSimpleName();
class BlockingBlurController implements BlurController {
private static final String TAG = BlockingBlurController.class.getSimpleName();
//Bitmap size should be divisible by 16 to meet stride requirement
private static final int ROUNDING_VALUE = 16;

Expand Down Expand Up @@ -77,7 +79,7 @@ public void run() {
* Can be Activity's root content layout (android.R.id.content)
* or some of your custom root layouts.
*/
public DefaultBlurController(@NonNull View blurView, @NonNull View rootView) {
public BlockingBlurController(@NonNull View blurView, @NonNull View rootView) {
this.rootView = rootView;
this.blurView = blurView;
this.blurAlgorithm = new RenderScriptBlur(blurView.getContext(), true);
Expand Down Expand Up @@ -189,11 +191,6 @@ private void setupInternalCanvasMatrix() {
internalCanvas.scale(1f / scaleFactorX, 1f / scaleFactorY);
}

@Override
public boolean isInternalCanvas(Canvas canvas) {
return internalCanvas == canvas;
}

/**
* Draws whole view hierarchy on internal canvas
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,6 @@ interface BlurController {
float DEFAULT_SCALE_FACTOR = 8f;
float DEFAULT_BLUR_RADIUS = 16f;

/**
* Used to distinct BlurController's Canvas from System Canvas.
* A View that uses BlurController should draw only on System Canvas.
* Otherwise their content will be blurred too.
*/
boolean isInternalCanvas(Canvas canvas);

/**
* Draws blurred content on given canvas
*/
Expand Down
31 changes: 19 additions & 12 deletions library/src/main/java/eightbitlab/com/blurview/BlurView.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

Expand All @@ -20,7 +21,7 @@ public class BlurView extends FrameLayout {
@ColorInt
private static final int TRANSPARENT = 0x00000000;

private BlurController blurController;
private BlurController blurController = createStubController();

@ColorInt
private int overlayColor;
Expand All @@ -41,7 +42,6 @@ public BlurView(Context context, AttributeSet attrs, int defStyleAttr) {
}

private void init(AttributeSet attrs, int defStyleAttr) {
createStubController();
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.BlurView, defStyleAttr, 0);
overlayColor = a.getColor(R.styleable.BlurView_blurOverlayColor, TRANSPARENT);
a.recycle();
Expand All @@ -52,10 +52,14 @@ private void init(AttributeSet attrs, int defStyleAttr) {

@Override
public void draw(Canvas canvas) {
if (!blurController.isInternalCanvas(canvas)) {
//draw only on system's hardware accelerated canvas
if (canvas.isHardwareAccelerated()) {
blurController.drawBlurredContent(canvas);
drawColorOverlay(canvas);
super.draw(canvas);
} else if (!isHardwareAccelerated()) {
//if view is in a not hardware accelerated window, don't draw blur
super.draw(canvas);
}
}

Expand Down Expand Up @@ -112,7 +116,10 @@ protected void onDetachedFromWindow() {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
startAutoBlurUpdate();

if (!isHardwareAccelerated()) {
Log.e(TAG, "BlurView can't be used in not hardware-accelerated window!");
}
}

private void setBlurController(@NonNull BlurController blurController) {
Expand All @@ -137,8 +144,13 @@ public void setOverlayColor(@ColorInt int overlayColor) {
* @return ControllerSettings to setup needed params.
*/
public ControllerSettings setupWith(View rootView) {
BlurController blurController = new DefaultBlurController(this, rootView);
BlurController blurController = new BlockingBlurController(this, rootView);
setBlurController(blurController);

if (!isHardwareAccelerated()) {
blurController.stopAutoBlurUpdate();
}

return new ControllerSettings(blurController);
}

Expand Down Expand Up @@ -180,13 +192,8 @@ public ControllerSettings windowBackground(@Nullable Drawable windowBackground)
/**
* Used in edit mode and in case if no BlurController was set
*/
private void createStubController() {
blurController = new BlurController() {
@Override
public boolean isInternalCanvas(Canvas canvas) {
return false;
}

private BlurController createStubController() {
return new BlurController() {
@Override
public void drawBlurredContent(Canvas canvas) {
}
Expand Down

0 comments on commit 17172c7

Please sign in to comment.