ThreadedRenderer.java revision e45b1fd03b524d2b57cc6c222d89076a31a08bea
1cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/*
2cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Copyright (C) 2013 The Android Open Source Project
3cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
4cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Licensed under the Apache License, Version 2.0 (the "License");
5cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * you may not use this file except in compliance with the License.
6cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * You may obtain a copy of the License at
7cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
8cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *      http://www.apache.org/licenses/LICENSE-2.0
9cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
10cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Unless required by applicable law or agreed to in writing, software
11cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * distributed under the License is distributed on an "AS IS" BASIS,
12cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * See the License for the specific language governing permissions and
14cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * limitations under the License.
15cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
16cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
17cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpackage android.view;
18cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
1904fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reckimport android.graphics.Bitmap;
20cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.graphics.Rect;
21cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.graphics.SurfaceTexture;
22cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.SystemClock;
23cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.os.Trace;
24cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.Surface.OutOfResourcesException;
25cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport android.view.View.AttachInfo;
26cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
27cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckimport java.io.PrintWriter;
28cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
29cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck/**
30cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Hardware renderer that proxies the rendering to a render thread. Most calls
314f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * are currently synchronous.
324f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * TODO: Make draw() async.
334f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * TODO: Figure out how to share the DisplayList between two threads (global lock?)
34cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
35cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * The UI thread can block on the RenderThread, but RenderThread must never
36cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * block on the UI thread.
37cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
384f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * ThreadedRenderer creates an instance of RenderProxy. RenderProxy in turn creates
394f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * and manages a CanvasContext on the RenderThread. The CanvasContext is fully managed
404f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck * by the lifecycle of the RenderProxy.
414f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck *
42cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * Note that although currently the EGL context & surfaces are created & managed
43cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * by the render thread, the goal is to move that into a shared structure that can
44cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * be managed by both threads. EGLSurface creation & deletion should ideally be
45cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * done on the UI thread and not the RenderThread to avoid stalling the
46cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * RenderThread with surface buffer allocation.
47cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck *
48cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck * @hide
49cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck */
50cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reckpublic class ThreadedRenderer extends HardwareRenderer {
51cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private static final String LOGTAG = "ThreadedRenderer";
52cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
53e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static final Rect NULL_RECT = new Rect();
54cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
55cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    private int mWidth, mHeight;
564f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private long mNativeProxy;
57f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private boolean mInitialized = false;
58bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private RenderNode mRootNode;
59cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
603dfe19f72cbd95b201e89376ae1810c5c9229b00John Reck    ThreadedRenderer(boolean translucent) {
61e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        long rootNodePtr = nCreateRootRenderNode();
62e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mRootNode = RenderNode.adopt(rootNodePtr);
63bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setClipToBounds(false);
64e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        mNativeProxy = nCreateProxy(translucent, rootNodePtr);
65cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
66cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
67cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
68cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroy(boolean full) {
69f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = false;
70f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(null);
71fae904d63947fe1687d1d44be29234cc3d538f24John Reck        nDestroyCanvasAndSurface(mNativeProxy);
72cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
73cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
74f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private void updateEnabledState(Surface surface) {
75f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        if (surface == null || !surface.isValid()) {
76f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(false);
77f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        } else {
78f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck            setEnabled(mInitialized);
79f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        }
80f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
81f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
82cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
83cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean initialize(Surface surface) throws OutOfResourcesException {
84f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        mInitialized = true;
85f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        return nInitialize(mNativeProxy, surface);
87cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
88cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
89cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
90cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void updateSurface(Surface surface) throws OutOfResourcesException {
91f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        updateEnabledState(surface);
924f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nUpdateSurface(mNativeProxy, surface);
93cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
94cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
95cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
96f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    void pauseSurface(Surface surface) {
97f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck        nPauseSurface(mNativeProxy, surface);
98f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    }
99f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck
100f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    @Override
101cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void destroyHardwareResources(View view) {
1024f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        destroyResources(view);
1034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        // TODO: GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
1044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    }
1054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1064f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static void destroyResources(View view) {
1074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        view.destroyHardwareResources();
1084f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1094f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (view instanceof ViewGroup) {
1104f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            ViewGroup group = (ViewGroup) view;
1114f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck
1124f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int count = group.getChildCount();
1134f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            for (int i = 0; i < count; i++) {
1144f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck                destroyResources(group.getChildAt(i));
1154f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            }
1164f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
117cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
118cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
119cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
120cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void invalidate(Surface surface) {
1214f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        updateSurface(surface);
122cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
123cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
124cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
125cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean safelyRun(Runnable action) {
126fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck        nRunWithGlContext(mNativeProxy, action);
127fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck        return true;
128cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
129cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
130cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
131cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setup(int width, int height) {
132cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mWidth = width;
133cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        mHeight = height;
134bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        mRootNode.setLeftTopRightBottom(0, 0, mWidth, mHeight);
1354f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        nSetup(mNativeProxy, width, height);
136cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
137cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
138cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
139cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getWidth() {
140cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mWidth;
141cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
142cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
143cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
144cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    int getHeight() {
145cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return mHeight;
146cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
147cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
148cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
149cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void dumpGfxInfo(PrintWriter pw) {
150cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        // TODO Auto-generated method stub
151cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
152cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
153cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
154cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    long getFrameCount() {
155cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        // TODO Auto-generated method stub
156cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        return 0;
157cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
158cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
159cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
160cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    boolean loadSystemProperties() {
1614f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        return false;
162cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
163cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
164cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    /**
165cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck     * TODO: Remove
166cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck     * Temporary hack to allow RenderThreadTest prototype app to trigger
167cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck     * replaying a DisplayList after modifying the displaylist properties
168cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck     *
169cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck     *  @hide */
170cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    public void repeatLastDraw() {
171cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
172cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
173bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    private void updateRootDisplayList(View view, HardwareDrawCallbacks callbacks) {
174cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags |= View.PFLAG_DRAWN;
175cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
176cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = (view.mPrivateFlags & View.PFLAG_INVALIDATED)
177cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck                == View.PFLAG_INVALIDATED;
178cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mPrivateFlags &= ~View.PFLAG_INVALIDATED;
179cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
180cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        Trace.traceBegin(Trace.TRACE_TAG_VIEW, "getDisplayList");
181bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        HardwareCanvas canvas = mRootNode.start(mWidth, mHeight);
18205e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        try {
18305e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            callbacks.onHardwarePostDraw(canvas);
18405e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            canvas.drawDisplayList(view.getDisplayList());
18505e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            callbacks.onHardwarePostDraw(canvas);
18605e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        } finally {
18705e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            mRootNode.end(canvas);
18805e858400adee0f579b1e27e321b48bd55843fbdJohn Reck            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
18905e858400adee0f579b1e27e321b48bd55843fbdJohn Reck        }
190cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
191cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        view.mRecreateDisplayList = false;
192bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    }
193bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
194bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    @Override
195bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck    void draw(View view, AttachInfo attachInfo, HardwareDrawCallbacks callbacks, Rect dirty) {
196bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mIgnoreDirtyState = true;
197bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        attachInfo.mDrawingTime = SystemClock.uptimeMillis();
198bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck
199bc0cc0220b830df54c8ed41d0b53daffd7f6c991John Reck        updateRootDisplayList(view, callbacks);
200cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2016313b9259d37b59f3402058e197637aa3014516cJohn Reck        attachInfo.mIgnoreDirtyState = false;
2026313b9259d37b59f3402058e197637aa3014516cJohn Reck
2034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        if (dirty == null) {
2044f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            dirty = NULL_RECT;
2054f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        }
206e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck        nSyncAndDrawFrame(mNativeProxy, dirty.left, dirty.top, dirty.right, dirty.bottom);
207cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
208cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
209cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
21019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void detachFunctor(long functor) {
211d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck        // no-op, we never attach functors to need to detach them
21219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
21319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
21419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
21519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void attachFunctor(AttachInfo attachInfo, long functor) {
216d3d8dafc2f61fb118c060720b52684c59303f3dbJohn Reck        invokeFunctor(functor, true);
217cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
218cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
219cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
220ae738a7a45d710115f8aedacf218d4bfa0b25698Bo Liu    void invokeFunctor(long functor, boolean waitForCompletion) {
2210d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck        nInvokeFunctor(mNativeProxy, functor, waitForCompletion);
2220d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    }
2230d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck
2240d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    @Override
22504fc583c3dd3144bc6b718fcac4b3e1afdfdb067John Reck    HardwareLayer createDisplayListLayer(int width, int height) {
22619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateDisplayListLayer(mNativeProxy, width, height);
22719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptDisplayListLayer(this, layer);
228cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
229cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
230cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
23119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    HardwareLayer createTextureLayer() {
23219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        long layer = nCreateTextureLayer(mNativeProxy);
23319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return HardwareLayer.adoptTextureLayer(this, layer);
234cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
235cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
236cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
23719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    SurfaceTexture createSurfaceTexture(final HardwareLayer layer) {
23819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        final SurfaceTexture[] ret = new SurfaceTexture[1];
23919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        nRunWithGlContext(mNativeProxy, new Runnable() {
24019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck            @Override
24119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck            public void run() {
24219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck                ret[0] = layer.createSurfaceTexture();
24319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck            }
24419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        });
24519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return ret[0];
246cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
247cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
248cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
24919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    boolean copyLayerInto(final HardwareLayer layer, final Bitmap bitmap) {
25019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        return nCopyLayerInto(mNativeProxy,
25119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck                layer.getDeferredLayerUpdater(), bitmap.mNativeBitmap);
252cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
253cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
254cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
25519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void pushLayerUpdate(HardwareLayer layer) {
25619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        // TODO: Remove this, it's not needed outside of GLRenderer
25719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
25819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
25919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
26019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerCreated(HardwareLayer layer) {
26119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        // TODO: Is this actually useful?
26219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
26319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
26419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
26519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void flushLayerUpdates() {
26619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        // TODO: Figure out what this should do or remove it
26719b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    }
26819b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
26919b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    @Override
27019b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    void onLayerDestroyed(HardwareLayer layer) {
27119b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck        nDestroyLayer(mNativeProxy, layer.getDeferredLayerUpdater());
272cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
273cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
274cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    @Override
275cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    void setName(String name) {
276cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
277cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2784f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    @Override
27928ad7b52e038ef0cdd89f753d9839444a434b299John Reck    void fence() {
28028ad7b52e038ef0cdd89f753d9839444a434b299John Reck        nFence(mNativeProxy);
28128ad7b52e038ef0cdd89f753d9839444a434b299John Reck    }
28228ad7b52e038ef0cdd89f753d9839444a434b299John Reck
28328ad7b52e038ef0cdd89f753d9839444a434b299John Reck    @Override
2844f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    protected void finalize() throws Throwable {
2854f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        try {
2864f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            nDeleteProxy(mNativeProxy);
2870ed751dd22a98f0c1f637570c5775b4f5e97d895John Reck            mNativeProxy = 0;
2884f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck        } finally {
2894f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            super.finalize();
290cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck        }
291cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck    }
292cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
2934f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    /** @hide */
2944f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    public static native void postToRenderThread(Runnable runnable);
295cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
296e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateRootRenderNode();
297e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native long nCreateProxy(boolean translucent, long rootRenderNode);
2984f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nDeleteProxy(long nativeProxy);
299cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3004f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native boolean nInitialize(long nativeProxy, Surface window);
3014f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nUpdateSurface(long nativeProxy, Surface window);
302f7d9c1dc84671d4e99657ef071d275700d85bb11John Reck    private static native void nPauseSurface(long nativeProxy, Surface window);
3034f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck    private static native void nSetup(long nativeProxy, int width, int height);
304be34f2f3b340196426bdf558b28951359a4d84faJohn Reck    private static native void nSetDisplayListData(long nativeProxy, long displayList,
30544fd8d24f761f82d21e9b00932648a1b6bf91449John Reck            long newData);
306e45b1fd03b524d2b57cc6c222d89076a31a08beaJohn Reck    private static native void nSyncAndDrawFrame(long nativeProxy,
3074f02bf4eef6af47f35c70c4dda5b7b9523d89ca0John Reck            int dirtyLeft, int dirtyTop, int dirtyRight, int dirtyBottom);
308fc53ef27793a39e9effd829e9cae02a9ca14147eJohn Reck    private static native void nRunWithGlContext(long nativeProxy, Runnable runnable);
309fae904d63947fe1687d1d44be29234cc3d538f24John Reck    private static native void nDestroyCanvasAndSurface(long nativeProxy);
310cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck
3110d1f634f4b5e1bb37aa51777efb6a68619488d01John Reck    private static native void nInvokeFunctor(long nativeProxy, long functor, boolean waitForCompletion);
31219b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck
31319b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateDisplayListLayer(long nativeProxy, int width, int height);
31419b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native long nCreateTextureLayer(long nativeProxy);
31519b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmap);
31619b6bcfd83eb7fb92ebd06d2fec89e308311f1d0John Reck    private static native void nDestroyLayer(long nativeProxy, long layer);
31728ad7b52e038ef0cdd89f753d9839444a434b299John Reck
31828ad7b52e038ef0cdd89f753d9839444a434b299John Reck    private static native void nFence(long nativeProxy);
319cec24ae16e9a0a7c3075f1a8d9149bb7fb3813fcJohn Reck}
320