diff options
| author | 2023-12-21 04:26:53 +0000 | |
|---|---|---|
| committer | 2023-12-21 04:26:53 +0000 | |
| commit | 454dbf123050f5ecd61abbf83dbb30841ec16975 (patch) | |
| tree | 690103692f9aaf48ac949248892e03cc94a42c84 | |
| parent | f8c8751f6fdee10675400245f1c091b42d93e60f (diff) | |
| parent | 419fcfd91b475d83dbd044a8a0bc5536c8e514ca (diff) | |
Merge "Perform magnification viewport drawing outside of WM global lock." into udc-dev am: 419fcfd91b
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/25583221
Change-Id: I162a6b373b5a7d60dc0a45f8f99bb4c6b8890114
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | services/core/java/com/android/server/wm/AccessibilityController.java | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index f3001133338a..b3ae2ee30f22 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -1280,45 +1280,53 @@ final class AccessibilityController { } void drawIfNeeded(SurfaceControl.Transaction t) { + // Drawing variables (alpha, dirty rect, and bounds) access is synchronized + // using WindowManagerGlobalLock. Grab copies of these values before + // drawing on the canvas so that drawing can be performed outside of the lock. + int alpha; + Rect drawingRect = null; + Region drawingBounds = null; synchronized (mService.mGlobalLock) { if (!mInvalidated) { return; } mInvalidated = false; - if (mAlpha > 0) { - Canvas canvas = null; - try { - // Empty dirty rectangle means unspecified. - if (mDirtyRect.isEmpty()) { - mBounds.getBounds(mDirtyRect); - } - mDirtyRect.inset(-mHalfBorderWidth, -mHalfBorderWidth); - canvas = mSurface.lockCanvas(mDirtyRect); - if (DEBUG_VIEWPORT_WINDOW) { - Slog.i(LOG_TAG, "Dirty rect: " + mDirtyRect); - } - } catch (IllegalArgumentException iae) { - /* ignore */ - } catch (Surface.OutOfResourcesException oore) { - /* ignore */ - } - if (canvas == null) { - return; + + alpha = mAlpha; + if (alpha > 0) { + drawingBounds = new Region(mBounds); + // Empty dirty rectangle means unspecified. + if (mDirtyRect.isEmpty()) { + mBounds.getBounds(mDirtyRect); } + mDirtyRect.inset(-mHalfBorderWidth, -mHalfBorderWidth); + drawingRect = new Rect(mDirtyRect); if (DEBUG_VIEWPORT_WINDOW) { - Slog.i(LOG_TAG, "Bounds: " + mBounds); + Slog.i(LOG_TAG, "ViewportWindow bounds: " + mBounds); + Slog.i(LOG_TAG, "ViewportWindow dirty rect: " + mDirtyRect); } - canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); - mPaint.setAlpha(mAlpha); - Path path = mBounds.getBoundaryPath(); - canvas.drawPath(path, mPaint); - - mSurface.unlockCanvasAndPost(canvas); - t.show(mSurfaceControl); - } else { - t.hide(mSurfaceControl); } } + + // Draw without holding WindowManagerGlobalLock. + if (alpha > 0) { + Canvas canvas = null; + try { + canvas = mSurface.lockCanvas(drawingRect); + } catch (IllegalArgumentException | OutOfResourcesException e) { + /* ignore */ + } + if (canvas == null) { + return; + } + canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); + mPaint.setAlpha(alpha); + canvas.drawPath(drawingBounds.getBoundaryPath(), mPaint); + mSurface.unlockCanvasAndPost(canvas); + t.show(mSurfaceControl); + } else { + t.hide(mSurfaceControl); + } } void releaseSurface() { |