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 <cstdint>
20 #include <map>
21 
22 #include <EGL/egl.h>
23 
24 struct ANativeWindow;
25 
26 struct EglSurface {
27     static std::map<uint32_t, EglSurface*> map;
28     static uint32_t nextId;
29 
EglSurfaceEglSurface30     EglSurface(EGLConfig config_, uint32_t ctx_, uint32_t width_, uint32_t height_)
31         : create_ctx(ctx_), config(config_), height(height_), width(width_), id(nextId++) {
32         map.emplace(id, this);
33     }
34 
~EglSurfaceEglSurface35     ~EglSurface() {
36         map.erase(id);
37     }
38 
bindEglSurface39     EglSurface* bind(uint32_t ctx_, bool read_) {
40         for (auto const& it : EglSurface::map) {
41             EglSurface* sur = it.second;
42             if (sur == this)
43                 continue;
44             if (sur->bound_ctx == ctx_) {
45                 if (read_ && sur->read)
46                     return sur;
47                 if (!read_ && sur->draw)
48                     return sur;
49             }
50         }
51         if (read_) {
52             read = true;
53         } else {
54             draw = true;
55         }
56         bound_ctx = ctx_;
57         return nullptr;
58     }
59 
unbindEglSurface60     void unbind(bool read_) {
61         if (read || draw) {
62             if (read_)
63                 read = false;
64             else
65                 draw = false;
66             if (read || draw)
67                 return;
68             bound_ctx = 0U;
69         }
70         return;
71     }
72 
disposableEglSurface73     bool disposable() {
74         return surface == EGL_NO_SURFACE && bound_ctx == 0U;
75     }
76 
77     EGLSurface surface = EGL_NO_SURFACE;
78     ANativeWindow* window = nullptr;
79     uint32_t create_ctx;
80     EGLConfig config;
81     uint32_t height;
82     uint32_t width;
83     uint32_t id;
84 
85   private:
86     uint32_t bound_ctx = 0U;
87     bool draw = false;
88     bool read = false;
89 };
90