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 #pragma once
18 
19 #include <EGL/egl.h>
20 #include <EGL/eglext.h>
21 
22 #include <gui/BufferQueueDefs.h>
23 
24 #include <SkImage.h>
25 #include <cutils/compiler.h>
26 #include <gui/BufferItem.h>
27 #include <system/graphics.h>
28 
29 namespace android {
30 
31 namespace uirenderer {
32 class RenderState;
33 }
34 
35 class AutoBackendTextureRelease;
36 class SurfaceTexture;
37 
38 /*
39  * ImageConsumer implements the parts of SurfaceTexture that deal with
40  * images consumed by HWUI view system.
41  */
42 class ImageConsumer {
43 public:
44     sk_sp<SkImage> dequeueImage(bool* queueEmpty, SurfaceTexture& cb,
45                                 uirenderer::RenderState& renderState);
46 
47     /**
48      * onAcquireBufferLocked amends the ConsumerBase method to update the
49      * mImageSlots array in addition to the ConsumerBase behavior.
50      */
51     void onAcquireBufferLocked(BufferItem* item);
52 
53     /**
54      * onReleaseBufferLocked amends the ConsumerBase method to update the
55      * mImageSlots array in addition to the ConsumerBase.
56      */
57     void onReleaseBufferLocked(int slot);
58 
59     /**
60      * onFreeBufferLocked frees up the given buffer slot. If the slot has been
61      * initialized this will release the reference to the GraphicBuffer in that
62      * slot and destroy the SkImage in that slot. Otherwise it has no effect.
63      */
64     void onFreeBufferLocked(int slotIndex);
65 
66 private:
67     /**
68      * ImageSlot contains the information and object references that
69      * ImageConsumer maintains about a BufferQueue buffer slot.
70      */
71     class ImageSlot {
72     public:
ImageSlot()73         ImageSlot() : mDataspace(HAL_DATASPACE_UNKNOWN), mEglFence(EGL_NO_SYNC_KHR) {}
74 
~ImageSlot()75         ~ImageSlot() { clear(); }
76 
77         void createIfNeeded(sp<GraphicBuffer> graphicBuffer, android_dataspace dataspace,
78                             bool forceCreate, GrContext* context);
79 
80         void clear();
81 
eglFence()82         inline EGLSyncKHR& eglFence() { return mEglFence; }
83 
84         sk_sp<SkImage> getImage();
85 
86     private:
87         // the dataspace associated with the current image
88         android_dataspace mDataspace;
89 
90         /**
91          * mEglFence is the EGL sync object that must signal before the buffer
92          * associated with this buffer slot may be dequeued.
93          */
94         EGLSyncKHR mEglFence;
95 
96         /**
97          * mTextureRelease may outlive ImageConsumer, if the last ref is held by an SkImage.
98          * ImageConsumer holds one ref to mTextureRelease, which is decremented by "clear".
99          */
100         AutoBackendTextureRelease* mTextureRelease = nullptr;
101     };
102 
103     /**
104      * ImageConsumer stores the SkImages that have been allocated by the BufferQueue
105      * for each buffer slot.  It is initialized to null pointers, and gets
106      * filled in with the result of BufferQueue::acquire when the
107      * client dequeues a buffer from a
108      * slot that has not yet been used. The buffer allocated to a slot will also
109      * be replaced if the requested buffer usage or geometry differs from that
110      * of the buffer allocated to a slot.
111      */
112     ImageSlot mImageSlots[BufferQueueDefs::NUM_BUFFER_SLOTS];
113 };
114 
115 } /* namespace android */
116