1a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon/* 2a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Copyright (C) 2012 The Android Open Source Project 3a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 4a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Licensed under the Apache License, Version 2.0 (the "License"); 5a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * you may not use this file except in compliance with the License. 6a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * You may obtain a copy of the License at 7a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 8a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * http://www.apache.org/licenses/LICENSE-2.0 9a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * 10a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * Unless required by applicable law or agreed to in writing, software 11a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * distributed under the License is distributed on an "AS IS" BASIS, 12a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * See the License for the specific language governing permissions and 14a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon * limitations under the License. 15a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon */ 16a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 17a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonpackage com.android.webview.chromium; 18a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 19a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport android.view.DisplayList; 20a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport android.view.HardwareCanvas; 21a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport android.view.ViewRootImpl; 22a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport android.util.Log; 23a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 24a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonimport org.chromium.content.common.CleanupReference; 25a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 26a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// Simple Java abstraction and wrapper for the native DrawGLFunctor flow. 27a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// An instance of this class can be constructed, bound to a single view context (i.e. AwContennts) 28a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// and then drawn and detached from the view tree any number of times (using requestDrawGL and 29a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// detach respectively). Then when finished with, it can be explicitly released by calling 30a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon// destroy() or will clean itself up as required via finalizer / CleanupReference. 31a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixonclass DrawGLFunctor { 32a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 33a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private static final String TAG = DrawGLFunctor.class.getSimpleName(); 34a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 35a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Pointer to native side instance 36a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private CleanupReference mCleanupReference; 37a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private DestroyRunnable mDestroyRunnable; 38a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 39a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public DrawGLFunctor(int viewContext) { 40a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mDestroyRunnable = new DestroyRunnable(nativeCreateGLFunctor(viewContext)); 41a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mCleanupReference = new CleanupReference(this, mDestroyRunnable); 42a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 43a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 44a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public void destroy() { 45a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (mCleanupReference != null) { 46a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mCleanupReference.cleanupNow(); 47a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mCleanupReference = null; 48a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mDestroyRunnable = null; 49a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 50a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 51a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 52a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public void detach() { 53a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mDestroyRunnable.detachNativeFunctor(); 54a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 55a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 5651f7cf16cd02f14050bb723175a2a57570e8486dTao Bai public boolean requestDrawGL(HardwareCanvas canvas, ViewRootImpl viewRootImpl) { 57a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (mDestroyRunnable.mNativeDrawGLFunctor == 0) { 58a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon throw new RuntimeException("requested DrawGL on already destroyed DrawGLFunctor"); 59a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 60a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mDestroyRunnable.mViewRootImpl = viewRootImpl; 6151f7cf16cd02f14050bb723175a2a57570e8486dTao Bai if (canvas != null) { 6251f7cf16cd02f14050bb723175a2a57570e8486dTao Bai int ret = canvas.callDrawGLFunction(mDestroyRunnable.mNativeDrawGLFunctor); 6351f7cf16cd02f14050bb723175a2a57570e8486dTao Bai if (ret != DisplayList.STATUS_DONE) { 6451f7cf16cd02f14050bb723175a2a57570e8486dTao Bai Log.e(TAG, "callDrawGLFunction error: " + ret); 6551f7cf16cd02f14050bb723175a2a57570e8486dTao Bai return false; 6651f7cf16cd02f14050bb723175a2a57570e8486dTao Bai } 6751f7cf16cd02f14050bb723175a2a57570e8486dTao Bai } else { 6851f7cf16cd02f14050bb723175a2a57570e8486dTao Bai viewRootImpl.attachFunctor(mDestroyRunnable.mNativeDrawGLFunctor); 6951f7cf16cd02f14050bb723175a2a57570e8486dTao Bai } 7051f7cf16cd02f14050bb723175a2a57570e8486dTao Bai return true; 71a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 72a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 73a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public static void setChromiumAwDrawGLFunction(int functionPointer) { 74a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon nativeSetChromiumAwDrawGLFunction(functionPointer); 75a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 76a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 77a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Holds the core resources of the class, everything required to correctly cleanup. 78a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // IMPORTANT: this class must not hold any reference back to the outer DrawGLFunctor 79a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // instance, as that will defeat GC of that object. 80a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private static final class DestroyRunnable implements Runnable { 81a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon ViewRootImpl mViewRootImpl; 82a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon int mNativeDrawGLFunctor; 83a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon DestroyRunnable(int nativeDrawGLFunctor) { 84a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mNativeDrawGLFunctor = nativeDrawGLFunctor; 85a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 86a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 87a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon // Called when the outer DrawGLFunctor instance has been GC'ed, i.e this is its finalizer. 88a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon @Override 89a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon public void run() { 90a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon detachNativeFunctor(); 91a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon nativeDestroyGLFunctor(mNativeDrawGLFunctor); 92a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mNativeDrawGLFunctor = 0; 93a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 94a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 95a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon void detachNativeFunctor() { 96a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon if (mNativeDrawGLFunctor != 0 && mViewRootImpl != null) { 97a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mViewRootImpl.detachFunctor(mNativeDrawGLFunctor); 98a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 99a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon mViewRootImpl = null; 100a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 101a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon } 102a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon 103a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private static native int nativeCreateGLFunctor(int viewContext); 104a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private static native void nativeDestroyGLFunctor(int functor); 105a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon private static native void nativeSetChromiumAwDrawGLFunction(int functionPointer); 106a2b0d0b4d6d1ff22fbb1329e358e1cc0a112aab3Jonathan Dixon} 107