1f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy/*
2f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * Copyright (C) 2010 The Android Open Source Project
3f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy *
4f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * Licensed under the Apache License, Version 2.0 (the "License");
5f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * you may not use this file except in compliance with the License.
6f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * You may obtain a copy of the License at
7f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy *
8f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy *      http://www.apache.org/licenses/LICENSE-2.0
9f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy *
10f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * Unless required by applicable law or agreed to in writing, software
11f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * distributed under the License is distributed on an "AS IS" BASIS,
12f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * See the License for the specific language governing permissions and
14f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * limitations under the License.
15f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy */
16f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy
17f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroypackage android.view;
18f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy
191c058e96b3fb5075c34b89cf22773373811abf7aJohn Reckimport android.annotation.NonNull;
20a753f4c6cb8558795e673df1896532cd148781e2Chris Craikimport android.annotation.Nullable;
21abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganovimport android.util.Pools.SynchronizedPool;
22f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy
23f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy/**
24f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * An implementation of a GL canvas that records drawing operations.
25f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * This is intended for use with a DisplayList. This class keeps a list of all the Paint and
26f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
27f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy * the DisplayList is still holding a native reference to the memory.
28f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy */
29abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganovclass GLES20RecordingCanvas extends GLES20Canvas {
30162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    // The recording canvas pool should be large enough to handle a deeply nested
31162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    // view hierarchy because display lists are generated recursively.
326d7475d666baefaa3ba9f0dcee25238739454241Romain Guy    private static final int POOL_LIMIT = 25;
33162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
34abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov    private static final SynchronizedPool<GLES20RecordingCanvas> sPool =
35abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov            new SynchronizedPool<GLES20RecordingCanvas>(POOL_LIMIT);
36162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
371c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck    RenderNode mNode;
381c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck
39162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    private GLES20RecordingCanvas() {
4084a4c887a07c1c2939443f4e0587d7f1ac109e4bJohn Reck        super();
41162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    }
42162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
431c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck    static GLES20RecordingCanvas obtain(@NonNull RenderNode node) {
441c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck        if (node == null) throw new IllegalArgumentException("node cannot be null");
45162a0217563f4665da6eb183dfce0fef740f641fJeff Brown        GLES20RecordingCanvas canvas = sPool.acquire();
46abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov        if (canvas == null) {
47abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov            canvas = new GLES20RecordingCanvas();
48abae2a1b891772d36d8f781adfcc8969e551691fSvetoslav Ganov        }
491c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck        canvas.mNode = node;
50162a0217563f4665da6eb183dfce0fef740f641fJeff Brown        return canvas;
51162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    }
52162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
53162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    void recycle() {
541c058e96b3fb5075c34b89cf22773373811abf7aJohn Reck        mNode = null;
55162a0217563f4665da6eb183dfce0fef740f641fJeff Brown        sPool.release(this);
56162a0217563f4665da6eb183dfce0fef740f641fJeff Brown    }
57162a0217563f4665da6eb183dfce0fef740f641fJeff Brown
5844fd8d24f761f82d21e9b00932648a1b6bf91449John Reck    long finishRecording() {
5944fd8d24f761f82d21e9b00932648a1b6bf91449John Reck        return nFinishRecording(mRenderer);
60ca479d468be963661fd82634f4b57f21c13f1fe6Chet Haase    }
61a753f4c6cb8558795e673df1896532cd148781e2Chris Craik
62a753f4c6cb8558795e673df1896532cd148781e2Chris Craik    @Override
63a753f4c6cb8558795e673df1896532cd148781e2Chris Craik    public boolean isRecordingFor(Object o) {
64a753f4c6cb8558795e673df1896532cd148781e2Chris Craik        return o == mNode;
65a753f4c6cb8558795e673df1896532cd148781e2Chris Craik    }
66f890fab5a6715548e520a6f010a3bfe7607ce56ePatrick Dubroy}
67