Home | History | Annotate | Download | only in system
      1 /*
      2  * Copyright (C) 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.systemui.shared.system;
     18 
     19 import android.graphics.Matrix;
     20 import android.graphics.Rect;
     21 import android.view.Surface;
     22 import android.view.SurfaceControl;
     23 import android.view.SurfaceControl.Transaction;
     24 import android.view.View;
     25 import android.view.ViewRootImpl;
     26 
     27 /**
     28  * Helper class to apply surface transactions in sync with RenderThread.
     29  */
     30 public class SyncRtSurfaceTransactionApplier {
     31 
     32     private final Surface mTargetSurface;
     33     private final ViewRootImpl mTargetViewRootImpl;
     34     private final float[] mTmpFloat9 = new float[9];
     35 
     36     /**
     37      * @param targetView The view in the surface that acts as synchronization anchor.
     38      */
     39     public SyncRtSurfaceTransactionApplier(View targetView) {
     40         mTargetViewRootImpl = targetView != null ? targetView.getViewRootImpl() : null;
     41         mTargetSurface = mTargetViewRootImpl != null ? mTargetViewRootImpl.mSurface : null;
     42     }
     43 
     44     /**
     45      * Schedules applying surface parameters on the next frame.
     46      *
     47      * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into
     48      *               this method to avoid synchronization issues.
     49      */
     50     public void scheduleApply(SurfaceParams... params) {
     51         if (mTargetViewRootImpl == null) {
     52             return;
     53         }
     54         mTargetViewRootImpl.registerRtFrameCallback(frame -> {
     55                 if (mTargetSurface == null || !mTargetSurface.isValid()) {
     56                     return;
     57                 }
     58                 Transaction t = new Transaction();
     59                 for (int i = params.length - 1; i >= 0; i--) {
     60                     SurfaceParams surfaceParams = params[i];
     61                     SurfaceControl surface = surfaceParams.surface;
     62                     t.deferTransactionUntilSurface(surface, mTargetSurface, frame);
     63                     applyParams(t, surfaceParams, mTmpFloat9);
     64                 }
     65                 t.setEarlyWakeup();
     66                 t.apply();
     67         });
     68 
     69         // Make sure a frame gets scheduled.
     70         mTargetViewRootImpl.getView().invalidate();
     71     }
     72 
     73     public static void applyParams(TransactionCompat t, SurfaceParams params) {
     74         applyParams(t.mTransaction, params, t.mTmpValues);
     75     }
     76 
     77     private static void applyParams(Transaction t, SurfaceParams params, float[] tmpFloat9) {
     78         t.setMatrix(params.surface, params.matrix, tmpFloat9);
     79         t.setWindowCrop(params.surface, params.windowCrop);
     80         t.setAlpha(params.surface, params.alpha);
     81         t.setLayer(params.surface, params.layer);
     82         t.show(params.surface);
     83     }
     84 
     85     public static class SurfaceParams {
     86 
     87         /**
     88          * Constructs surface parameters to be applied when the current view state gets pushed to
     89          * RenderThread.
     90          *
     91          * @param surface The surface to modify.
     92          * @param alpha Alpha to apply.
     93          * @param matrix Matrix to apply.
     94          * @param windowCrop Crop to apply.
     95          */
     96         public SurfaceParams(SurfaceControlCompat surface, float alpha, Matrix matrix,
     97                 Rect windowCrop, int layer) {
     98             this.surface = surface.mSurfaceControl;
     99             this.alpha = alpha;
    100             this.matrix = new Matrix(matrix);
    101             this.windowCrop = new Rect(windowCrop);
    102             this.layer = layer;
    103         }
    104 
    105         final SurfaceControl surface;
    106         final float alpha;
    107         final Matrix matrix;
    108         final Rect windowCrop;
    109         final int layer;
    110     }
    111 }
    112