1 /*
2  * Copyright 2014 The Android Open Source Project
3  * Copyright (C) 2014 Mozilla Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include "GonkBufferItem.h"
19 
20 #include <ui/Fence.h>
21 #include <ui/GraphicBuffer.h>
22 
23 #include <system/window.h>
24 
25 namespace android {
26 
GonkBufferItem()27 GonkBufferItem::GonkBufferItem() :
28     mTransform(0),
29     mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
30     mTimestamp(0),
31     mIsAutoTimestamp(false),
32     mFrameNumber(0),
33     mSlot(INVALID_BUFFER_SLOT),
34     mIsDroppable(false),
35     mAcquireCalled(false),
36     mTransformToDisplayInverse(false) {
37     mCrop.makeInvalid();
38 }
39 
operator IGonkGraphicBufferConsumer::BufferItem() const40 GonkBufferItem::operator IGonkGraphicBufferConsumer::BufferItem() const {
41     IGonkGraphicBufferConsumer::BufferItem bufferItem;
42     bufferItem.mGraphicBuffer = mGraphicBuffer;
43     bufferItem.mFence = mFence;
44     bufferItem.mCrop = mCrop;
45     bufferItem.mTransform = mTransform;
46     bufferItem.mScalingMode = mScalingMode;
47     bufferItem.mTimestamp = mTimestamp;
48     bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
49     bufferItem.mFrameNumber = mFrameNumber;
50     bufferItem.mBuf = mSlot;
51     bufferItem.mIsDroppable = mIsDroppable;
52     bufferItem.mAcquireCalled = mAcquireCalled;
53     bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
54     return bufferItem;
55 }
56 
getPodSize() const57 size_t GonkBufferItem::getPodSize() const {
58     size_t c =  sizeof(mCrop) +
59             sizeof(mTransform) +
60             sizeof(mScalingMode) +
61             sizeof(mTimestamp) +
62             sizeof(mIsAutoTimestamp) +
63             sizeof(mFrameNumber) +
64             sizeof(mSlot) +
65             sizeof(mIsDroppable) +
66             sizeof(mAcquireCalled) +
67             sizeof(mTransformToDisplayInverse);
68     return c;
69 }
70 
getFlattenedSize() const71 size_t GonkBufferItem::getFlattenedSize() const {
72     size_t c = 0;
73     if (mGraphicBuffer != 0) {
74         c += mGraphicBuffer->getFlattenedSize();
75         FlattenableUtils::align<4>(c);
76     }
77     if (mFence != 0) {
78         c += mFence->getFlattenedSize();
79         FlattenableUtils::align<4>(c);
80     }
81     return sizeof(int32_t) + c + getPodSize();
82 }
83 
getFdCount() const84 size_t GonkBufferItem::getFdCount() const {
85     size_t c = 0;
86     if (mGraphicBuffer != 0) {
87         c += mGraphicBuffer->getFdCount();
88     }
89     if (mFence != 0) {
90         c += mFence->getFdCount();
91     }
92     return c;
93 }
94 
flatten(void * & buffer,size_t & size,int * & fds,size_t & count) const95 status_t GonkBufferItem::flatten(
96         void*& buffer, size_t& size, int*& fds, size_t& count) const {
97 
98     // make sure we have enough space
99     if (count < GonkBufferItem::getFlattenedSize()) {
100         return NO_MEMORY;
101     }
102 
103     // content flags are stored first
104     uint32_t& flags = *static_cast<uint32_t*>(buffer);
105 
106     // advance the pointer
107     FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
108 
109     flags = 0;
110     if (mGraphicBuffer != 0) {
111         status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
112         if (err) return err;
113         size -= FlattenableUtils::align<4>(buffer);
114         flags |= 1;
115     }
116     if (mFence != 0) {
117         status_t err = mFence->flatten(buffer, size, fds, count);
118         if (err) return err;
119         size -= FlattenableUtils::align<4>(buffer);
120         flags |= 2;
121     }
122 
123     // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
124     if (size < getPodSize()) {
125         return NO_MEMORY;
126     }
127 
128     FlattenableUtils::write(buffer, size, mCrop);
129     FlattenableUtils::write(buffer, size, mTransform);
130     FlattenableUtils::write(buffer, size, mScalingMode);
131     FlattenableUtils::write(buffer, size, mTimestamp);
132     FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
133     FlattenableUtils::write(buffer, size, mFrameNumber);
134     FlattenableUtils::write(buffer, size, mSlot);
135     FlattenableUtils::write(buffer, size, mIsDroppable);
136     FlattenableUtils::write(buffer, size, mAcquireCalled);
137     FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
138 
139     return NO_ERROR;
140 }
141 
unflatten(void const * & buffer,size_t & size,int const * & fds,size_t & count)142 status_t GonkBufferItem::unflatten(
143         void const*& buffer, size_t& size, int const*& fds, size_t& count) {
144 
145     if (size < sizeof(uint32_t))
146         return NO_MEMORY;
147 
148     uint32_t flags = 0;
149     FlattenableUtils::read(buffer, size, flags);
150 
151     if (flags & 1) {
152         mGraphicBuffer = new GraphicBuffer();
153         status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
154         if (err) return err;
155         size -= FlattenableUtils::align<4>(buffer);
156     }
157 
158     if (flags & 2) {
159         mFence = new Fence();
160         status_t err = mFence->unflatten(buffer, size, fds, count);
161         if (err) return err;
162         size -= FlattenableUtils::align<4>(buffer);
163     }
164 
165     // check we have enough space
166     if (size < getPodSize()) {
167         return NO_MEMORY;
168     }
169 
170     FlattenableUtils::read(buffer, size, mCrop);
171     FlattenableUtils::read(buffer, size, mTransform);
172     FlattenableUtils::read(buffer, size, mScalingMode);
173     FlattenableUtils::read(buffer, size, mTimestamp);
174     FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
175     FlattenableUtils::read(buffer, size, mFrameNumber);
176     FlattenableUtils::read(buffer, size, mSlot);
177     FlattenableUtils::read(buffer, size, mIsDroppable);
178     FlattenableUtils::read(buffer, size, mAcquireCalled);
179     FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
180 
181     return NO_ERROR;
182 }
183 
scalingModeName(uint32_t scalingMode)184 const char* GonkBufferItem::scalingModeName(uint32_t scalingMode) {
185     switch (scalingMode) {
186         case NATIVE_WINDOW_SCALING_MODE_FREEZE: return "FREEZE";
187         case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW: return "SCALE_TO_WINDOW";
188         case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP: return "SCALE_CROP";
189         default: return "Unknown";
190     }
191 }
192 
193 } // namespace android
194