1 /*
2  * Copyright (C) 2015 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 #ifndef ANDROID_DRM_FRAMEBUFFER_
18 #define ANDROID_DRM_FRAMEBUFFER_
19 
20 #include <stdint.h>
21 #include <sync/sync.h>
22 #include <ui/GraphicBuffer.h>
23 
24 namespace android {
25 
26 struct DrmFramebuffer {
DrmFramebufferDrmFramebuffer27   DrmFramebuffer() : release_fence_fd_(-1) {
28   }
29 
~DrmFramebufferDrmFramebuffer30   ~DrmFramebuffer() {
31     if (release_fence_fd() >= 0)
32       close(release_fence_fd());
33   }
34 
is_validDrmFramebuffer35   bool is_valid() {
36     return buffer_ != NULL;
37   }
38 
bufferDrmFramebuffer39   sp<GraphicBuffer> buffer() {
40     return buffer_;
41   }
42 
release_fence_fdDrmFramebuffer43   int release_fence_fd() {
44     return release_fence_fd_;
45   }
46 
set_release_fence_fdDrmFramebuffer47   void set_release_fence_fd(int fd) {
48     if (release_fence_fd_ >= 0)
49       close(release_fence_fd_);
50     release_fence_fd_ = fd;
51   }
52 
AllocateDrmFramebuffer53   bool Allocate(uint32_t w, uint32_t h) {
54     if (is_valid()) {
55       if (buffer_->getWidth() == w && buffer_->getHeight() == h)
56         return true;
57 
58       if (release_fence_fd_ >= 0) {
59         if (sync_wait(release_fence_fd_, kReleaseWaitTimeoutMs) != 0) {
60           ALOGE("Wait for release fence failed\n");
61           return false;
62         }
63       }
64       Clear();
65     }
66     buffer_ = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_888,
67                                 GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER |
68                                     GRALLOC_USAGE_HW_COMPOSER);
69     release_fence_fd_ = -1;
70     return is_valid();
71   }
72 
ClearDrmFramebuffer73   void Clear() {
74     if (!is_valid())
75       return;
76 
77     if (release_fence_fd_ >= 0) {
78       close(release_fence_fd_);
79       release_fence_fd_ = -1;
80     }
81 
82     buffer_.clear();
83   }
84 
WaitReleasedDrmFramebuffer85   int WaitReleased(int timeout_milliseconds) {
86     if (!is_valid())
87       return 0;
88     if (release_fence_fd_ < 0)
89       return 0;
90 
91     int ret = sync_wait(release_fence_fd_, timeout_milliseconds);
92     return ret;
93   }
94 
95   // Somewhat arbitrarily chosen, but wanted to stay below 3000ms, which is the
96   // system timeout
97   static const int kReleaseWaitTimeoutMs = 1500;
98 
99  private:
100   sp<GraphicBuffer> buffer_;
101   int release_fence_fd_;
102 };
103 }  // namespace android
104 
105 #endif  // ANDROID_DRM_FRAMEBUFFER_
106