1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/nativewindow/IGonkGraphicBufferConsumer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,480 @@ 1.4 +/* 1.5 + * Copyright (C) 2013 The Android Open Source Project 1.6 + * 1.7 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.8 + * you may not use this file except in compliance with the License. 1.9 + * You may obtain a copy of the License at 1.10 + * 1.11 + * http://www.apache.org/licenses/LICENSE-2.0 1.12 + * 1.13 + * Unless required by applicable law or agreed to in writing, software 1.14 + * distributed under the License is distributed on an "AS IS" BASIS, 1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.16 + * See the License for the specific language governing permissions and 1.17 + * limitations under the License. 1.18 + */ 1.19 + 1.20 +#define EGL_EGLEXT_PROTOTYPES 1.21 + 1.22 +#include <stdint.h> 1.23 +#include <sys/types.h> 1.24 + 1.25 +#include <utils/Errors.h> 1.26 + 1.27 +#include <binder/Parcel.h> 1.28 +#include <binder/IInterface.h> 1.29 + 1.30 +#include <gui/IConsumerListener.h> 1.31 +#include "IGonkGraphicBufferConsumer.h" 1.32 + 1.33 +#include <ui/GraphicBuffer.h> 1.34 +#include <ui/Fence.h> 1.35 + 1.36 +#include <system/window.h> 1.37 + 1.38 +namespace android { 1.39 +// --------------------------------------------------------------------------- 1.40 + 1.41 +IGonkGraphicBufferConsumer::BufferItem::BufferItem() : 1.42 + mTransform(0), 1.43 + mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE), 1.44 + mTimestamp(0), 1.45 + mIsAutoTimestamp(false), 1.46 + mFrameNumber(0), 1.47 + mBuf(INVALID_BUFFER_SLOT), 1.48 + mIsDroppable(false), 1.49 + mAcquireCalled(false), 1.50 + mTransformToDisplayInverse(false) { 1.51 + mCrop.makeInvalid(); 1.52 +} 1.53 + 1.54 +size_t IGonkGraphicBufferConsumer::BufferItem::getPodSize() const { 1.55 + size_t c = sizeof(mCrop) + 1.56 + sizeof(mTransform) + 1.57 + sizeof(mScalingMode) + 1.58 + sizeof(mTimestamp) + 1.59 + sizeof(mIsAutoTimestamp) + 1.60 + sizeof(mFrameNumber) + 1.61 + sizeof(mBuf) + 1.62 + sizeof(mIsDroppable) + 1.63 + sizeof(mAcquireCalled) + 1.64 + sizeof(mTransformToDisplayInverse); 1.65 + return c; 1.66 +} 1.67 + 1.68 +size_t IGonkGraphicBufferConsumer::BufferItem::getFlattenedSize() const { 1.69 + size_t c = 0; 1.70 + if (mGraphicBuffer != 0) { 1.71 + c += mGraphicBuffer->getFlattenedSize(); 1.72 + FlattenableUtils::align<4>(c); 1.73 + } 1.74 + if (mFence != 0) { 1.75 + c += mFence->getFlattenedSize(); 1.76 + FlattenableUtils::align<4>(c); 1.77 + } 1.78 + return sizeof(int32_t) + c + getPodSize(); 1.79 +} 1.80 + 1.81 +size_t IGonkGraphicBufferConsumer::BufferItem::getFdCount() const { 1.82 + size_t c = 0; 1.83 + if (mGraphicBuffer != 0) { 1.84 + c += mGraphicBuffer->getFdCount(); 1.85 + } 1.86 + if (mFence != 0) { 1.87 + c += mFence->getFdCount(); 1.88 + } 1.89 + return c; 1.90 +} 1.91 + 1.92 +status_t IGonkGraphicBufferConsumer::BufferItem::flatten( 1.93 + void*& buffer, size_t& size, int*& fds, size_t& count) const { 1.94 + 1.95 + // make sure we have enough space 1.96 + if (count < BufferItem::getFlattenedSize()) { 1.97 + return NO_MEMORY; 1.98 + } 1.99 + 1.100 + // content flags are stored first 1.101 + uint32_t& flags = *static_cast<uint32_t*>(buffer); 1.102 + 1.103 + // advance the pointer 1.104 + FlattenableUtils::advance(buffer, size, sizeof(uint32_t)); 1.105 + 1.106 + flags = 0; 1.107 + if (mGraphicBuffer != 0) { 1.108 + status_t err = mGraphicBuffer->flatten(buffer, size, fds, count); 1.109 + if (err) return err; 1.110 + size -= FlattenableUtils::align<4>(buffer); 1.111 + flags |= 1; 1.112 + } 1.113 + if (mFence != 0) { 1.114 + status_t err = mFence->flatten(buffer, size, fds, count); 1.115 + if (err) return err; 1.116 + size -= FlattenableUtils::align<4>(buffer); 1.117 + flags |= 2; 1.118 + } 1.119 + 1.120 + // check we have enough space (in case flattening the fence/graphicbuffer lied to us) 1.121 + if (size < getPodSize()) { 1.122 + return NO_MEMORY; 1.123 + } 1.124 + 1.125 + FlattenableUtils::write(buffer, size, mCrop); 1.126 + FlattenableUtils::write(buffer, size, mTransform); 1.127 + FlattenableUtils::write(buffer, size, mScalingMode); 1.128 + FlattenableUtils::write(buffer, size, mTimestamp); 1.129 + FlattenableUtils::write(buffer, size, mIsAutoTimestamp); 1.130 + FlattenableUtils::write(buffer, size, mFrameNumber); 1.131 + FlattenableUtils::write(buffer, size, mBuf); 1.132 + FlattenableUtils::write(buffer, size, mIsDroppable); 1.133 + FlattenableUtils::write(buffer, size, mAcquireCalled); 1.134 + FlattenableUtils::write(buffer, size, mTransformToDisplayInverse); 1.135 + 1.136 + return NO_ERROR; 1.137 +} 1.138 + 1.139 +status_t IGonkGraphicBufferConsumer::BufferItem::unflatten( 1.140 + void const*& buffer, size_t& size, int const*& fds, size_t& count) { 1.141 + 1.142 + if (size < sizeof(uint32_t)) 1.143 + return NO_MEMORY; 1.144 + 1.145 + uint32_t flags = 0; 1.146 + FlattenableUtils::read(buffer, size, flags); 1.147 + 1.148 + if (flags & 1) { 1.149 + mGraphicBuffer = new GraphicBuffer(); 1.150 + status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count); 1.151 + if (err) return err; 1.152 + size -= FlattenableUtils::align<4>(buffer); 1.153 + } 1.154 + 1.155 + if (flags & 2) { 1.156 + mFence = new Fence(); 1.157 + status_t err = mFence->unflatten(buffer, size, fds, count); 1.158 + if (err) return err; 1.159 + size -= FlattenableUtils::align<4>(buffer); 1.160 + } 1.161 + 1.162 + // check we have enough space 1.163 + if (size < getPodSize()) { 1.164 + return NO_MEMORY; 1.165 + } 1.166 + 1.167 + FlattenableUtils::read(buffer, size, mCrop); 1.168 + FlattenableUtils::read(buffer, size, mTransform); 1.169 + FlattenableUtils::read(buffer, size, mScalingMode); 1.170 + FlattenableUtils::read(buffer, size, mTimestamp); 1.171 + FlattenableUtils::read(buffer, size, mIsAutoTimestamp); 1.172 + FlattenableUtils::read(buffer, size, mFrameNumber); 1.173 + FlattenableUtils::read(buffer, size, mBuf); 1.174 + FlattenableUtils::read(buffer, size, mIsDroppable); 1.175 + FlattenableUtils::read(buffer, size, mAcquireCalled); 1.176 + FlattenableUtils::read(buffer, size, mTransformToDisplayInverse); 1.177 + 1.178 + return NO_ERROR; 1.179 +} 1.180 + 1.181 +// --------------------------------------------------------------------------- 1.182 + 1.183 +enum { 1.184 + ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION, 1.185 + RELEASE_BUFFER, 1.186 + CONSUMER_CONNECT, 1.187 + CONSUMER_DISCONNECT, 1.188 + GET_RELEASED_BUFFERS, 1.189 + SET_DEFAULT_BUFFER_SIZE, 1.190 + SET_DEFAULT_MAX_BUFFER_COUNT, 1.191 + DISABLE_ASYNC_BUFFER, 1.192 + SET_MAX_ACQUIRED_BUFFER_COUNT, 1.193 + SET_CONSUMER_NAME, 1.194 + SET_DEFAULT_BUFFER_FORMAT, 1.195 + SET_CONSUMER_USAGE_BITS, 1.196 + SET_TRANSFORM_HINT, 1.197 + DUMP, 1.198 +}; 1.199 + 1.200 +class BpGonkGraphicBufferConsumer : public BpInterface<IGonkGraphicBufferConsumer> 1.201 +{ 1.202 +public: 1.203 + BpGonkGraphicBufferConsumer(const sp<IBinder>& impl) 1.204 + : BpInterface<IGonkGraphicBufferConsumer>(impl) 1.205 + { 1.206 + } 1.207 + 1.208 + virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) { 1.209 + Parcel data, reply; 1.210 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.211 + data.writeInt64(presentWhen); 1.212 + status_t result = remote()->transact(ACQUIRE_BUFFER, data, &reply); 1.213 + if (result != NO_ERROR) { 1.214 + return result; 1.215 + } 1.216 + result = reply.read(*buffer); 1.217 + if (result != NO_ERROR) { 1.218 + return result; 1.219 + } 1.220 + return reply.readInt32(); 1.221 + } 1.222 + 1.223 + virtual status_t releaseBuffer(int buf, uint64_t frameNumber, 1.224 + const sp<Fence>& releaseFence) { 1.225 + Parcel data, reply; 1.226 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.227 + data.writeInt32(buf); 1.228 + data.writeInt64(frameNumber); 1.229 + data.write(*releaseFence); 1.230 + status_t result = remote()->transact(RELEASE_BUFFER, data, &reply); 1.231 + if (result != NO_ERROR) { 1.232 + return result; 1.233 + } 1.234 + return reply.readInt32(); 1.235 + } 1.236 + 1.237 + virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) { 1.238 + Parcel data, reply; 1.239 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.240 + data.writeStrongBinder(consumer->asBinder()); 1.241 + data.writeInt32(controlledByApp); 1.242 + status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply); 1.243 + if (result != NO_ERROR) { 1.244 + return result; 1.245 + } 1.246 + return reply.readInt32(); 1.247 + } 1.248 + 1.249 + virtual status_t consumerDisconnect() { 1.250 + Parcel data, reply; 1.251 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.252 + status_t result = remote()->transact(CONSUMER_DISCONNECT, data, &reply); 1.253 + if (result != NO_ERROR) { 1.254 + return result; 1.255 + } 1.256 + return reply.readInt32(); 1.257 + } 1.258 + 1.259 + virtual status_t getReleasedBuffers(uint32_t* slotMask) { 1.260 + Parcel data, reply; 1.261 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.262 + status_t result = remote()->transact(GET_RELEASED_BUFFERS, data, &reply); 1.263 + if (result != NO_ERROR) { 1.264 + return result; 1.265 + } 1.266 + *slotMask = reply.readInt32(); 1.267 + return reply.readInt32(); 1.268 + } 1.269 + 1.270 + virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) { 1.271 + Parcel data, reply; 1.272 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.273 + data.writeInt32(w); 1.274 + data.writeInt32(h); 1.275 + status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply); 1.276 + if (result != NO_ERROR) { 1.277 + return result; 1.278 + } 1.279 + return reply.readInt32(); 1.280 + } 1.281 + 1.282 + virtual status_t setDefaultMaxBufferCount(int bufferCount) { 1.283 + Parcel data, reply; 1.284 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.285 + data.writeInt32(bufferCount); 1.286 + status_t result = remote()->transact(SET_DEFAULT_MAX_BUFFER_COUNT, data, &reply); 1.287 + if (result != NO_ERROR) { 1.288 + return result; 1.289 + } 1.290 + return reply.readInt32(); 1.291 + } 1.292 + 1.293 + virtual status_t disableAsyncBuffer() { 1.294 + Parcel data, reply; 1.295 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.296 + status_t result = remote()->transact(DISABLE_ASYNC_BUFFER, data, &reply); 1.297 + if (result != NO_ERROR) { 1.298 + return result; 1.299 + } 1.300 + return reply.readInt32(); 1.301 + } 1.302 + 1.303 + virtual status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers) { 1.304 + Parcel data, reply; 1.305 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.306 + data.writeInt32(maxAcquiredBuffers); 1.307 + status_t result = remote()->transact(SET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply); 1.308 + if (result != NO_ERROR) { 1.309 + return result; 1.310 + } 1.311 + return reply.readInt32(); 1.312 + } 1.313 + 1.314 + virtual void setConsumerName(const String8& name) { 1.315 + Parcel data, reply; 1.316 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.317 + data.writeString8(name); 1.318 + remote()->transact(SET_CONSUMER_NAME, data, &reply); 1.319 + } 1.320 + 1.321 + virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) { 1.322 + Parcel data, reply; 1.323 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.324 + data.writeInt32(defaultFormat); 1.325 + status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply); 1.326 + if (result != NO_ERROR) { 1.327 + return result; 1.328 + } 1.329 + return reply.readInt32(); 1.330 + } 1.331 + 1.332 + virtual status_t setConsumerUsageBits(uint32_t usage) { 1.333 + Parcel data, reply; 1.334 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.335 + data.writeInt32(usage); 1.336 + status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply); 1.337 + if (result != NO_ERROR) { 1.338 + return result; 1.339 + } 1.340 + return reply.readInt32(); 1.341 + } 1.342 + 1.343 + virtual status_t setTransformHint(uint32_t hint) { 1.344 + Parcel data, reply; 1.345 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.346 + data.writeInt32(hint); 1.347 + status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply); 1.348 + if (result != NO_ERROR) { 1.349 + return result; 1.350 + } 1.351 + return reply.readInt32(); 1.352 + } 1.353 + 1.354 + virtual void dump(String8& result, const char* prefix) const { 1.355 + Parcel data, reply; 1.356 + data.writeInterfaceToken(IGonkGraphicBufferConsumer::getInterfaceDescriptor()); 1.357 + data.writeString8(result); 1.358 + data.writeString8(String8(prefix ? prefix : "")); 1.359 + remote()->transact(DUMP, data, &reply); 1.360 + reply.readString8(); 1.361 + } 1.362 +}; 1.363 + 1.364 +IMPLEMENT_META_INTERFACE(GonkGraphicBufferConsumer, "android.gui.IGonkGraphicBufferConsumer"); 1.365 +// ---------------------------------------------------------------------- 1.366 + 1.367 +status_t BnGonkGraphicBufferConsumer::onTransact( 1.368 + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) 1.369 +{ 1.370 + switch(code) { 1.371 + case ACQUIRE_BUFFER: { 1.372 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.373 + BufferItem item; 1.374 + int64_t presentWhen = data.readInt64(); 1.375 + status_t result = acquireBuffer(&item, presentWhen); 1.376 + status_t err = reply->write(item); 1.377 + if (err) return err; 1.378 + reply->writeInt32(result); 1.379 + return NO_ERROR; 1.380 + } break; 1.381 + case RELEASE_BUFFER: { 1.382 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.383 + int buf = data.readInt32(); 1.384 + uint64_t frameNumber = data.readInt64(); 1.385 + sp<Fence> releaseFence = new Fence(); 1.386 + status_t err = data.read(*releaseFence); 1.387 + if (err) return err; 1.388 + status_t result = releaseBuffer(buf, frameNumber, releaseFence); 1.389 + reply->writeInt32(result); 1.390 + return NO_ERROR; 1.391 + } break; 1.392 + 1.393 + case CONSUMER_CONNECT: { 1.394 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.395 + sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() ); 1.396 + bool controlledByApp = data.readInt32(); 1.397 + status_t result = consumerConnect(consumer, controlledByApp); 1.398 + reply->writeInt32(result); 1.399 + return NO_ERROR; 1.400 + } break; 1.401 + 1.402 + case CONSUMER_DISCONNECT: { 1.403 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.404 + status_t result = consumerDisconnect(); 1.405 + reply->writeInt32(result); 1.406 + return NO_ERROR; 1.407 + } break; 1.408 + case GET_RELEASED_BUFFERS: { 1.409 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.410 + uint32_t slotMask; 1.411 + status_t result = getReleasedBuffers(&slotMask); 1.412 + reply->writeInt32(slotMask); 1.413 + reply->writeInt32(result); 1.414 + return NO_ERROR; 1.415 + } break; 1.416 + case SET_DEFAULT_BUFFER_SIZE: { 1.417 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.418 + uint32_t w = data.readInt32(); 1.419 + uint32_t h = data.readInt32(); 1.420 + status_t result = setDefaultBufferSize(w, h); 1.421 + reply->writeInt32(result); 1.422 + return NO_ERROR; 1.423 + } break; 1.424 + case SET_DEFAULT_MAX_BUFFER_COUNT: { 1.425 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.426 + uint32_t bufferCount = data.readInt32(); 1.427 + status_t result = setDefaultMaxBufferCount(bufferCount); 1.428 + reply->writeInt32(result); 1.429 + return NO_ERROR; 1.430 + } break; 1.431 + case DISABLE_ASYNC_BUFFER: { 1.432 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.433 + status_t result = disableAsyncBuffer(); 1.434 + reply->writeInt32(result); 1.435 + return NO_ERROR; 1.436 + } break; 1.437 + case SET_MAX_ACQUIRED_BUFFER_COUNT: { 1.438 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.439 + uint32_t maxAcquiredBuffers = data.readInt32(); 1.440 + status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers); 1.441 + reply->writeInt32(result); 1.442 + return NO_ERROR; 1.443 + } break; 1.444 + case SET_CONSUMER_NAME: { 1.445 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.446 + setConsumerName( data.readString8() ); 1.447 + return NO_ERROR; 1.448 + } break; 1.449 + case SET_DEFAULT_BUFFER_FORMAT: { 1.450 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.451 + uint32_t defaultFormat = data.readInt32(); 1.452 + status_t result = setDefaultBufferFormat(defaultFormat); 1.453 + reply->writeInt32(result); 1.454 + return NO_ERROR; 1.455 + } break; 1.456 + case SET_CONSUMER_USAGE_BITS: { 1.457 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.458 + uint32_t usage = data.readInt32(); 1.459 + status_t result = setConsumerUsageBits(usage); 1.460 + reply->writeInt32(result); 1.461 + return NO_ERROR; 1.462 + } break; 1.463 + case SET_TRANSFORM_HINT: { 1.464 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.465 + uint32_t hint = data.readInt32(); 1.466 + status_t result = setTransformHint(hint); 1.467 + reply->writeInt32(result); 1.468 + return NO_ERROR; 1.469 + } break; 1.470 + 1.471 + case DUMP: { 1.472 + CHECK_INTERFACE(IGonkGraphicBufferConsumer, data, reply); 1.473 + String8 result = data.readString8(); 1.474 + String8 prefix = data.readString8(); 1.475 + static_cast<IGonkGraphicBufferConsumer*>(this)->dump(result, prefix); 1.476 + reply->writeString8(result); 1.477 + return NO_ERROR; 1.478 + } 1.479 + } 1.480 + return BBinder::onTransact(code, data, reply, flags); 1.481 +} 1.482 + 1.483 +}; // namespace android