开发者选项 Force GPU renering

本文详细解析了Android系统中强制GPU渲染的工作流程,从设置属性到系统服务响应,再到硬件加速的启用,涉及DevelopmentSettings.java、Binder.cpp、misc.cpp等关键文件。设置属性后,需调用setWindowManager才能生效,期间涉及ViewRootImpl、HardwareRenderer和GLES20Canvas等组件,最终实现UI的GPU加速渲染。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


设置这个属性不会立即生效。只有调用setWindowManager才能生效,而setWindowManager只有Activity建立的时候调用。

 1../packages/apps/Settings/src/com/android/settings/DevelopmentSettings.java

在setting设置属性。给所有服务通过binder发送命令SYSPROPS_TRANSACTION

./apps/Settings/res/values/strings.xml:4033:    <string name="force_hw_ui">Force GPU rendering</string>

private static final String HARDWARE_UI_PROPERTY = "persist.sys.ui.hw";



    private void writeHardwareUiOptions() {
        SystemProperties.set(HARDWARE_UI_PROPERTY, mForceHardwareUi.isChecked() ? "true" : "false");
        pokeSystemProperties();
    }


   void pokeSystemProperties() {
        if (!mDontPokeProperties) {
            //noinspection unchecked
            (new SystemPropPoker()).execute();
        }
    }


      static class SystemPropPoker extends AsyncTask<Void, Void, Void> {
        @Override
        protected Void doInBackground(Void... params) {
            String[] services;
            try {
                services = ServiceManager.listServices();
            } catch (RemoteException e) {
                return null;
            }
            for (String service : services) {
                IBinder obj = ServiceManager.checkService(service);
                if (obj != null) {
                    Parcel data = Parcel.obtain();
                    try {
                        obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0);
                    } catch (RemoteException e) {
                    } catch (Exception e) {
                        Log.i("DevSettings", "Somone wrote a bad service '" + service
                                + "' that doesn't like to be poked: " + e);
                    }
                    data.recycle();
                }
            }
            return null;
        }
    }

1.1 frameworks/native/libs/binder/Binder.cpp

server接受SYSPROPS_TRANSACTION命令

        case SYSPROPS_TRANSACTION: {
            report_sysprop_change();
            return NO_ERROR;
        }


1.2 frameworks/native/libs/utils/misc.cpp


回调

void report_sysprop_change() {
#if defined(HAVE_PTHREADS)
    pthread_mutex_lock(&gSyspropMutex);
    Vector<sysprop_change_callback_info> listeners;
    if (gSyspropList != NULL) {
        listeners = *gSyspropList;
    }
    pthread_mutex_unlock(&gSyspropMutex);
    
    //ALOGI("Reporting sysprop change to %d listeners", listeners.size());
    for (size_t i=0; i<listeners.size(); i++) {
        listeners[i].callback();
    }
#endif
}   


注册回调函数

void add_sysprop_change_callback(sysprop_change_callback cb, int priority) {
#if defined(HAVE_PTHREADS)
    pthread_mutex_lock(&gSyspropMutex);
    if (gSyspropList == NULL) {
        gSyspropList = new Vector<sysprop_change_callback_info>();
    }
    sysprop_change_callback_info info;
    info.callback = cb;
    info.priority = priority;
    bool added = false;
    for (size_t i=0; i<gSyspropList->size(); i++) {
        if (priority >= gSyspropList->itemAt(i).priority) {
            gSyspropList->insertAt(info, i);
            added = true;
            break;
        }
    }
    if (!added) {
        gSyspropList->add(info);
    }
    pthread_mutex_unlock(&gSyspropMutex);
#endif
}


static void SystemProperties_add_change_callback(JNIEnv *env, jobject clazz)
{
    // This is called with the Java lock held.
    if (sVM == NULL) {
        env->GetJavaVM(&sVM);
    }
    if (sClazz == NULL) {
        sClazz = (jclass) env->NewGlobalRef(clazz);
        sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V");
        add_sysprop_change_callback(do_report_sysprop_change, -10000);
    }
}


1.3 frameworks/base/core/jni/android_os_SystemProperties.cpp

    { "native_add_change_callback", "()V",
      (void*) SystemProperties_add_change_callback },




1.4 frameworks/base/core/java/android/os/SystemProperties.java

    public static void addChangeCallback(Runnable callback) {
        synchronized (sChangeCallbacks) {
            if (sChangeCallbacks.size() == 0) {
                native_add_change_callback();
            }
            sChangeCallbacks.add(callback);
        }
    }

1.5 frameworks/base/core/java/android/view/WindowManagerGlobal.java

   public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) 

                                          

            if (mSystemPropertyUpdater == null) {
                mSystemPropertyUpdater = new Runnable() {
                    @Override public void run() {
                        synchronized (mLock) {
                            for (ViewRootImpl viewRoot : mRoots) {
                                viewRoot.loadSystemProperties();
                            }
                        }
                    }
                };
                SystemProperties.addChangeCallback(mSystemPropertyUpdater);
            }

           

1.6 frameworks/base/core/java/android/view/ViewRootImpl.java

   public void loadSystemProperties() {
        boolean layout = SystemProperties.getBoolean(
                View.DEBUG_LAYOUT_PROPERTY, false);
        if (layout != mAttachInfo.mDebugLayout) {
            mAttachInfo.mDebugLayout = layout;
            if (!mHandler.hasMessages(MSG_INVALIDATE_WORLD)) {
                mHandler.sendEmptyMessageDelayed(MSG_INVALIDATE_WORLD, 200);
            }
        }
    }


      case MSG_INVALIDATE_WORLD: {
                if (mView != null) {
                    invalidateWorld(mView);
                }


   void invalidateWorld(View view) {
        view.invalidate();
        if (view instanceof ViewGroup) {
            ViewGroup parent = (ViewGroup) view;
            for (int i = 0; i < parent.getChildCount(); i++) {
                invalidateWorld(parent.getChildAt(i));
            }
        }
    }


   void invalidate() {
        mDirty.set(0, 0, mWidth, mHeight);
        scheduleTraversals();
    }

   void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            scheduleConsumeBatchedInput();
        }
    }

    final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }

   void doTraversal() {
        if (mTraversalScheduled) {
            mTraversalScheduled = false;
            mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);

            if (mProfile) {
                Debug.startMethodTracing("ViewAncestor");
            }

            Trace.traceBegin(Trace.TRACE_TAG_VIEW, "performTraversals");
            try {
                performTraversals();
            } finally {
                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
            }

            if (mProfile) {
                Debug.stopMethodTracing();
                mProfile = false;
            }
        }
    }



在doTraversal过程中,不会调用setWindowManager, 也就是强制GPU不会立即生效。


2.frameworks/base/core/java/android/view/Window.java

persist.sys.ui.hw属性只有在setWindowManager函数会得到这个属性。然后会判断这个属性调用gpu画ui。

   public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated
                || SystemProperties.getBoolean(PROPERTY_HARDWARE_UI, false);

        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }




       if (mHardwareAccelerated) {
            wp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
        }


3../base/core/java/android/view/ViewRootImpl.java

    private void enableHardwareAcceleration(Context context, WindowManager.LayoutParams attrs) {
        mAttachInfo.mHardwareAccelerated = false;
        mAttachInfo.mHardwareAccelerationRequested = false;

        // Don't enable hardware acceleration when the application is in compatibility mode
        if (mTranslator != null) return;

        // Try to enable hardware acceleration if requested
        final boolean hardwareAccelerated =
                (attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;

        if (hardwareAccelerated) {
            if (!HardwareRenderer.isAvailable()) {
                return;
            }


        mAttachInfo.mHardwareRenderer = HardwareRenderer.createGlRenderer(2, translucent);

4.java/android/view/HardwareRenderer.java

    public static boolean isAvailable() {
        return GLES20Canvas.isAvailable();
    }


   static HardwareRenderer createGlRenderer(int glVersion, boolean translucent) {
        switch (glVersion) {
            case 2:
                return Gl20Renderer.create(translucent);
        }       
        throw new IllegalArgumentException("Unknown GL version: " + glVersion);
    }



        static HardwareRenderer create(boolean translucent) {
            if (GLES20Canvas.isAvailable()) {
                return new Gl20Renderer(translucent);
            }
            return null;
        }


5./core/java/android/view/GLES20Canvas.java

   private static native boolean nIsAvailable(); 

   private static boolean sIsAvailable = nIsAvailable();

    static boolean isAvailable() {
        return sIsAvailable;
    }


6../base/core/java/android/view/ViewRootImpl.java

  private void draw(boolean fullRedrawNeeded){

       if (!dirty.isEmpty() || mIsAnimating) {
            if (attachInfo.mHardwareRenderer != null && attachInfo.mHardwareRenderer.isEnabled()) {
                // Draw with hardware renderer.                                                                              
                mIsAnimating = false;          
                mHardwareYOffset = yoff;       
                mResizeAlpha = resizeAlpha;    

                mCurrentDirty.set(dirty);                                                                                    
                mCurrentDirty.union(mPreviousDirty);
                mPreviousDirty.set(dirty);     
                dirty.setEmpty();              

                if (attachInfo.mHardwareRenderer.draw(mView, attachInfo, this,                                               
                        animating ? null : mCurrentDirty)) {
                    mPreviousDirty.set(0, 0, mWidth, mHeight);
                }
            } else if (!drawSoftware(surface, attachInfo, yoff, scalingRequired, dirty)) {                                   
                return;
            }
        }


1138         boolean draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
1139                 Rect dirty) {

                                           1214                         callbacks.onHardwarePreDraw(canvas);


    public void onHardwarePostDraw(HardwareCanvas canvas) {
        if (mResizeBuffer != null) {
            mResizePaint.setAlpha(mResizeAlpha);
            canvas.drawHardwareLayer(mResizeBuffer, 0.0f, mHardwareYOffset, mResizePaint);
        }
        drawAccessibilityFocusedDrawableIfNeeded(canvas);
    }   



7.     frameworks/base/core/java/android/view/GLES20Canvas.java

    void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
        final GLES20Layer glLayer = (GLES20Layer) layer;
        final int nativePaint = paint == null ? 0 : paint.mNativePaint;
        nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
    }
        
    private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);


8.frameworks/base/core/jni/android_view_GLES20Canvas.cpp

static void android_view_GLES20Canvas_drawLayer(JNIEnv* env, jobject clazz,
        OpenGLRenderer* renderer, Layer* layer, jfloat x, jfloat y, SkPaint* paint) {
    renderer->drawLayer(layer, x, y, paint);
}

9.frameworks/base/libs/hwui/OpenGLRenderer.cpp

status_t OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint)







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值