widget/gonk/nativewindow/GonkNativeWindowClientJB.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /*
michael@0 2 * Copyright (C) 2010 The Android Open Source Project
michael@0 3 * Copyright (C) 2013 Mozilla Foundation
michael@0 4 *
michael@0 5 * Licensed under the Apache License, Version 2.0 (the "License");
michael@0 6 * you may not use this file except in compliance with the License.
michael@0 7 * You may obtain a copy of the License at
michael@0 8 *
michael@0 9 * http://www.apache.org/licenses/LICENSE-2.0
michael@0 10 *
michael@0 11 * Unless required by applicable law or agreed to in writing, software
michael@0 12 * distributed under the License is distributed on an "AS IS" BASIS,
michael@0 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
michael@0 14 * See the License for the specific language governing permissions and
michael@0 15 * limitations under the License.
michael@0 16 */
michael@0 17
michael@0 18 #define LOG_TAG "GonkNativeWindowClient"
michael@0 19 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
michael@0 20 //#define LOG_NDEBUG 0
michael@0 21
michael@0 22 #include <android/native_window.h>
michael@0 23 #if ANDROID_VERSION == 17
michael@0 24 #include <utils/Trace.h>
michael@0 25 #else
michael@0 26 #include <cutils/trace.h>
michael@0 27 #endif
michael@0 28
michael@0 29 #include <binder/Parcel.h>
michael@0 30 #include <utils/Log.h>
michael@0 31 #include <ui/Fence.h>
michael@0 32
michael@0 33 #include "GonkNativeWindowClientJB.h"
michael@0 34
michael@0 35 namespace android {
michael@0 36
michael@0 37 GonkNativeWindowClient::GonkNativeWindowClient(
michael@0 38 const sp<IGraphicBufferProducer>& bufferProducer)
michael@0 39 : mBufferProducer(bufferProducer)
michael@0 40 {
michael@0 41 // Initialize the ANativeWindow function pointers.
michael@0 42 ANativeWindow::setSwapInterval = hook_setSwapInterval;
michael@0 43 ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
michael@0 44 ANativeWindow::cancelBuffer = hook_cancelBuffer;
michael@0 45 ANativeWindow::queueBuffer = hook_queueBuffer;
michael@0 46 ANativeWindow::query = hook_query;
michael@0 47 ANativeWindow::perform = hook_perform;
michael@0 48
michael@0 49 ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
michael@0 50 ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
michael@0 51 ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
michael@0 52 ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
michael@0 53
michael@0 54 const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
michael@0 55 const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
michael@0 56
michael@0 57 mReqWidth = 0;
michael@0 58 mReqHeight = 0;
michael@0 59 mReqFormat = 0;
michael@0 60 mReqUsage = 0;
michael@0 61 mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
michael@0 62 mCrop.clear();
michael@0 63 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
michael@0 64 mTransform = 0;
michael@0 65 mDefaultWidth = 0;
michael@0 66 mDefaultHeight = 0;
michael@0 67 mUserWidth = 0;
michael@0 68 mUserHeight = 0;
michael@0 69 mTransformHint = 0;
michael@0 70 mConsumerRunningBehind = false;
michael@0 71 mConnectedToCpu = false;
michael@0 72 }
michael@0 73
michael@0 74 GonkNativeWindowClient::~GonkNativeWindowClient() {
michael@0 75 if (mConnectedToCpu) {
michael@0 76 GonkNativeWindowClient::disconnect(NATIVE_WINDOW_API_CPU);
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 #if ANDROID_VERSION == 17
michael@0 81 sp<IGraphicBufferProducer> GonkNativeWindowClient::getISurfaceTexture() const {
michael@0 82 #else
michael@0 83 sp<IGraphicBufferProducer> GonkNativeWindowClient::getIGraphicBufferProducer() const {
michael@0 84 #endif
michael@0 85 return mBufferProducer;
michael@0 86 }
michael@0 87
michael@0 88 int GonkNativeWindowClient::hook_setSwapInterval(ANativeWindow* window, int interval) {
michael@0 89 GonkNativeWindowClient* c = getSelf(window);
michael@0 90 return c->setSwapInterval(interval);
michael@0 91 }
michael@0 92
michael@0 93 int GonkNativeWindowClient::hook_dequeueBuffer(ANativeWindow* window,
michael@0 94 ANativeWindowBuffer** buffer, int* fenceFd) {
michael@0 95 GonkNativeWindowClient* c = getSelf(window);
michael@0 96 return c->dequeueBuffer(buffer, fenceFd);
michael@0 97 }
michael@0 98
michael@0 99 int GonkNativeWindowClient::hook_cancelBuffer(ANativeWindow* window,
michael@0 100 ANativeWindowBuffer* buffer, int fenceFd) {
michael@0 101 GonkNativeWindowClient* c = getSelf(window);
michael@0 102 return c->cancelBuffer(buffer, fenceFd);
michael@0 103 }
michael@0 104
michael@0 105 int GonkNativeWindowClient::hook_queueBuffer(ANativeWindow* window,
michael@0 106 ANativeWindowBuffer* buffer, int fenceFd) {
michael@0 107 GonkNativeWindowClient* c = getSelf(window);
michael@0 108 return c->queueBuffer(buffer, fenceFd);
michael@0 109 }
michael@0 110
michael@0 111 int GonkNativeWindowClient::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
michael@0 112 ANativeWindowBuffer** buffer) {
michael@0 113 GonkNativeWindowClient* c = getSelf(window);
michael@0 114 ANativeWindowBuffer* buf;
michael@0 115 int fenceFd = -1;
michael@0 116 int result = c->dequeueBuffer(&buf, &fenceFd);
michael@0 117 sp<Fence> fence(new Fence(fenceFd));
michael@0 118 #if ANDROID_VERSION == 17
michael@0 119 int waitResult = fence->waitForever(1000, "dequeueBuffer_DEPRECATED");
michael@0 120 #else
michael@0 121 int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
michael@0 122 #endif
michael@0 123 if (waitResult != OK) {
michael@0 124 ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d",
michael@0 125 waitResult);
michael@0 126 c->cancelBuffer(buf, -1);
michael@0 127 return waitResult;
michael@0 128 }
michael@0 129 *buffer = buf;
michael@0 130 return result;
michael@0 131 }
michael@0 132
michael@0 133 int GonkNativeWindowClient::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
michael@0 134 ANativeWindowBuffer* buffer) {
michael@0 135 GonkNativeWindowClient* c = getSelf(window);
michael@0 136 return c->cancelBuffer(buffer, -1);
michael@0 137 }
michael@0 138
michael@0 139 int GonkNativeWindowClient::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
michael@0 140 ANativeWindowBuffer* buffer) {
michael@0 141 GonkNativeWindowClient* c = getSelf(window);
michael@0 142 return c->lockBuffer_DEPRECATED(buffer);
michael@0 143 }
michael@0 144
michael@0 145 int GonkNativeWindowClient::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
michael@0 146 ANativeWindowBuffer* buffer) {
michael@0 147 GonkNativeWindowClient* c = getSelf(window);
michael@0 148 return c->queueBuffer(buffer, -1);
michael@0 149 }
michael@0 150
michael@0 151 int GonkNativeWindowClient::hook_query(const ANativeWindow* window,
michael@0 152 int what, int* value) {
michael@0 153 const GonkNativeWindowClient* c = getSelf(window);
michael@0 154 return c->query(what, value);
michael@0 155 }
michael@0 156
michael@0 157 int GonkNativeWindowClient::hook_perform(ANativeWindow* window, int operation, ...) {
michael@0 158 va_list args;
michael@0 159 va_start(args, operation);
michael@0 160 GonkNativeWindowClient* c = getSelf(window);
michael@0 161 return c->perform(operation, args);
michael@0 162 }
michael@0 163
michael@0 164 int GonkNativeWindowClient::setSwapInterval(int interval) {
michael@0 165 // EGL specification states:
michael@0 166 // interval is silently clamped to minimum and maximum implementation
michael@0 167 // dependent values before being stored.
michael@0 168 // Although we don't have to, we apply the same logic here.
michael@0 169
michael@0 170 if (interval < minSwapInterval)
michael@0 171 interval = minSwapInterval;
michael@0 172
michael@0 173 if (interval > maxSwapInterval)
michael@0 174 interval = maxSwapInterval;
michael@0 175
michael@0 176 status_t res = mBufferProducer->setSynchronousMode(interval ? true : false);
michael@0 177
michael@0 178 return res;
michael@0 179 }
michael@0 180
michael@0 181 int GonkNativeWindowClient::dequeueBuffer(android_native_buffer_t** buffer,
michael@0 182 int* fenceFd) {
michael@0 183 ALOGV("GonkNativeWindowClient::dequeueBuffer");
michael@0 184 Mutex::Autolock lock(mMutex);
michael@0 185 int buf = -1;
michael@0 186 int reqW = mReqWidth ? mReqWidth : mUserWidth;
michael@0 187 int reqH = mReqHeight ? mReqHeight : mUserHeight;
michael@0 188 sp<Fence> fence;
michael@0 189 #if ANDROID_VERSION == 17
michael@0 190 status_t result = mBufferProducer->dequeueBuffer(&buf, fence,
michael@0 191 reqW, reqH, mReqFormat, mReqUsage);
michael@0 192 #else
michael@0 193 status_t result = mBufferProducer->dequeueBuffer(&buf, &fence,
michael@0 194 reqW, reqH, mReqFormat, mReqUsage);
michael@0 195 #endif
michael@0 196
michael@0 197 if (result < 0) {
michael@0 198 ALOGV("dequeueBuffer: dequeueBuffer(%d, %d, %d, %d)"
michael@0 199 "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
michael@0 200 result);
michael@0 201 return result;
michael@0 202 }
michael@0 203 sp<GraphicBuffer>& gbuf(mSlots[buf].buffer);
michael@0 204 if (result & IGraphicBufferProducer::RELEASE_ALL_BUFFERS) {
michael@0 205 freeAllBuffers();
michael@0 206 }
michael@0 207
michael@0 208 if ((result & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
michael@0 209 result = mBufferProducer->requestBuffer(buf, &gbuf);
michael@0 210
michael@0 211 if (result != NO_ERROR) {
michael@0 212 ALOGE("dequeueBuffer: requestBuffer failed: %d",
michael@0 213 result);
michael@0 214 return result;
michael@0 215 }
michael@0 216 }
michael@0 217
michael@0 218 if (fence.get() && fence->isValid()) {
michael@0 219 *fenceFd = fence->dup();
michael@0 220 if (*fenceFd == -1) {
michael@0 221 ALOGE("dequeueBuffer: error duping fence: %d", errno);
michael@0 222 // dup() should never fail; something is badly wrong. Soldier on
michael@0 223 // and hope for the best; the worst that should happen is some
michael@0 224 // visible corruption that lasts until the next frame.
michael@0 225 }
michael@0 226 } else {
michael@0 227 *fenceFd = -1;
michael@0 228 }
michael@0 229
michael@0 230 *buffer = gbuf.get();
michael@0 231 return OK;
michael@0 232 }
michael@0 233
michael@0 234 int GonkNativeWindowClient::cancelBuffer(android_native_buffer_t* buffer,
michael@0 235 int fenceFd) {
michael@0 236 ALOGV("GonkNativeWindowClient::cancelBuffer");
michael@0 237 Mutex::Autolock lock(mMutex);
michael@0 238 int i = getSlotFromBufferLocked(buffer);
michael@0 239 if (i < 0) {
michael@0 240 return i;
michael@0 241 }
michael@0 242 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
michael@0 243 mBufferProducer->cancelBuffer(i, fence);
michael@0 244 return OK;
michael@0 245 }
michael@0 246
michael@0 247 int GonkNativeWindowClient::getSlotFromBufferLocked(
michael@0 248 android_native_buffer_t* buffer) const {
michael@0 249 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
michael@0 250 if (mSlots[i].buffer != NULL &&
michael@0 251 mSlots[i].buffer->handle == buffer->handle) {
michael@0 252 return i;
michael@0 253 }
michael@0 254 }
michael@0 255 ALOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
michael@0 256 return BAD_VALUE;
michael@0 257 }
michael@0 258
michael@0 259 int GonkNativeWindowClient::lockBuffer_DEPRECATED(android_native_buffer_t* buffer) {
michael@0 260 ALOGV("GonkNativeWindowClient::lockBuffer");
michael@0 261 Mutex::Autolock lock(mMutex);
michael@0 262 return OK;
michael@0 263 }
michael@0 264
michael@0 265 int GonkNativeWindowClient::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
michael@0 266 ALOGV("GonkNativeWindowClient::queueBuffer");
michael@0 267 Mutex::Autolock lock(mMutex);
michael@0 268 int64_t timestamp;
michael@0 269 if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
michael@0 270 timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
michael@0 271 ALOGV("GonkNativeWindowClient::queueBuffer making up timestamp: %.2f ms",
michael@0 272 timestamp / 1000000.f);
michael@0 273 } else {
michael@0 274 timestamp = mTimestamp;
michael@0 275 }
michael@0 276 int i = getSlotFromBufferLocked(buffer);
michael@0 277 if (i < 0) {
michael@0 278 return i;
michael@0 279 }
michael@0 280
michael@0 281
michael@0 282 // Make sure the crop rectangle is entirely inside the buffer.
michael@0 283 Rect crop;
michael@0 284 mCrop.intersect(Rect(buffer->width, buffer->height), &crop);
michael@0 285
michael@0 286 sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
michael@0 287 IGraphicBufferProducer::QueueBufferOutput output;
michael@0 288
michael@0 289 IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
michael@0 290 mTransform, fence);
michael@0 291 status_t err = mBufferProducer->queueBuffer(i, input, &output);
michael@0 292 if (err != OK) {
michael@0 293 ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
michael@0 294 }
michael@0 295 uint32_t numPendingBuffers = 0;
michael@0 296 output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
michael@0 297 &numPendingBuffers);
michael@0 298
michael@0 299 mConsumerRunningBehind = (numPendingBuffers >= 2);
michael@0 300
michael@0 301 return err;
michael@0 302 }
michael@0 303
michael@0 304 int GonkNativeWindowClient::query(int what, int* value) const {
michael@0 305 ALOGV("GonkNativeWindowClient::query");
michael@0 306 { // scope for the lock
michael@0 307 Mutex::Autolock lock(mMutex);
michael@0 308 switch (what) {
michael@0 309 case NATIVE_WINDOW_FORMAT:
michael@0 310 if (mReqFormat) {
michael@0 311 *value = mReqFormat;
michael@0 312 return NO_ERROR;
michael@0 313 }
michael@0 314 break;
michael@0 315 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: {
michael@0 316 //sp<ISurfaceComposer> composer(
michael@0 317 // ComposerService::getComposerService());
michael@0 318 //if (composer->authenticateSurfaceTexture(mBufferProducer)) {
michael@0 319 // *value = 1;
michael@0 320 //} else {
michael@0 321 *value = 0;
michael@0 322 //}
michael@0 323 return NO_ERROR;
michael@0 324 }
michael@0 325 case NATIVE_WINDOW_CONCRETE_TYPE:
michael@0 326 #if ANDROID_VERSION == 17
michael@0 327 *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
michael@0 328 #else
michael@0 329 *value = NATIVE_WINDOW_SURFACE;
michael@0 330 #endif
michael@0 331 return NO_ERROR;
michael@0 332 case NATIVE_WINDOW_DEFAULT_WIDTH:
michael@0 333 *value = mUserWidth ? mUserWidth : mDefaultWidth;
michael@0 334 return NO_ERROR;
michael@0 335 case NATIVE_WINDOW_DEFAULT_HEIGHT:
michael@0 336 *value = mUserHeight ? mUserHeight : mDefaultHeight;
michael@0 337 return NO_ERROR;
michael@0 338 case NATIVE_WINDOW_TRANSFORM_HINT:
michael@0 339 *value = mTransformHint;
michael@0 340 return NO_ERROR;
michael@0 341 case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
michael@0 342 status_t err = NO_ERROR;
michael@0 343 if (!mConsumerRunningBehind) {
michael@0 344 *value = 0;
michael@0 345 } else {
michael@0 346 err = mBufferProducer->query(what, value);
michael@0 347 if (err == NO_ERROR) {
michael@0 348 mConsumerRunningBehind = *value;
michael@0 349 }
michael@0 350 }
michael@0 351 return err;
michael@0 352 }
michael@0 353 }
michael@0 354 }
michael@0 355
michael@0 356 return mBufferProducer->query(what, value);
michael@0 357 }
michael@0 358
michael@0 359 int GonkNativeWindowClient::perform(int operation, va_list args)
michael@0 360 {
michael@0 361 int res = NO_ERROR;
michael@0 362 switch (operation) {
michael@0 363 case NATIVE_WINDOW_CONNECT:
michael@0 364 // deprecated. must return NO_ERROR.
michael@0 365 break;
michael@0 366 case NATIVE_WINDOW_DISCONNECT:
michael@0 367 // deprecated. must return NO_ERROR.
michael@0 368 break;
michael@0 369 case NATIVE_WINDOW_SET_USAGE:
michael@0 370 res = dispatchSetUsage(args);
michael@0 371 break;
michael@0 372 case NATIVE_WINDOW_SET_CROP:
michael@0 373 res = dispatchSetCrop(args);
michael@0 374 break;
michael@0 375 case NATIVE_WINDOW_SET_BUFFER_COUNT:
michael@0 376 res = dispatchSetBufferCount(args);
michael@0 377 break;
michael@0 378 case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
michael@0 379 res = dispatchSetBuffersGeometry(args);
michael@0 380 break;
michael@0 381 case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
michael@0 382 res = dispatchSetBuffersTransform(args);
michael@0 383 break;
michael@0 384 case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
michael@0 385 res = dispatchSetBuffersTimestamp(args);
michael@0 386 break;
michael@0 387 case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
michael@0 388 res = dispatchSetBuffersDimensions(args);
michael@0 389 break;
michael@0 390 case NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS:
michael@0 391 res = dispatchSetBuffersUserDimensions(args);
michael@0 392 break;
michael@0 393 case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
michael@0 394 res = dispatchSetBuffersFormat(args);
michael@0 395 break;
michael@0 396 case NATIVE_WINDOW_LOCK:
michael@0 397 res = dispatchLock(args);
michael@0 398 break;
michael@0 399 case NATIVE_WINDOW_UNLOCK_AND_POST:
michael@0 400 res = dispatchUnlockAndPost(args);
michael@0 401 break;
michael@0 402 case NATIVE_WINDOW_SET_SCALING_MODE:
michael@0 403 res = dispatchSetScalingMode(args);
michael@0 404 break;
michael@0 405 case NATIVE_WINDOW_API_CONNECT:
michael@0 406 res = dispatchConnect(args);
michael@0 407 break;
michael@0 408 case NATIVE_WINDOW_API_DISCONNECT:
michael@0 409 res = dispatchDisconnect(args);
michael@0 410 break;
michael@0 411 default:
michael@0 412 res = NAME_NOT_FOUND;
michael@0 413 break;
michael@0 414 }
michael@0 415 return res;
michael@0 416 }
michael@0 417
michael@0 418 int GonkNativeWindowClient::dispatchConnect(va_list args) {
michael@0 419 int api = va_arg(args, int);
michael@0 420 return connect(api);
michael@0 421 }
michael@0 422
michael@0 423 int GonkNativeWindowClient::dispatchDisconnect(va_list args) {
michael@0 424 int api = va_arg(args, int);
michael@0 425 return disconnect(api);
michael@0 426 }
michael@0 427
michael@0 428 int GonkNativeWindowClient::dispatchSetUsage(va_list args) {
michael@0 429 int usage = va_arg(args, int);
michael@0 430 return setUsage(usage);
michael@0 431 }
michael@0 432
michael@0 433 int GonkNativeWindowClient::dispatchSetCrop(va_list args) {
michael@0 434 android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
michael@0 435 return setCrop(reinterpret_cast<Rect const*>(rect));
michael@0 436 }
michael@0 437
michael@0 438 int GonkNativeWindowClient::dispatchSetBufferCount(va_list args) {
michael@0 439 size_t bufferCount = va_arg(args, size_t);
michael@0 440 return setBufferCount(bufferCount);
michael@0 441 }
michael@0 442
michael@0 443 int GonkNativeWindowClient::dispatchSetBuffersGeometry(va_list args) {
michael@0 444 int w = va_arg(args, int);
michael@0 445 int h = va_arg(args, int);
michael@0 446 int f = va_arg(args, int);
michael@0 447 int err = setBuffersDimensions(w, h);
michael@0 448 if (err != 0) {
michael@0 449 return err;
michael@0 450 }
michael@0 451 return setBuffersFormat(f);
michael@0 452 }
michael@0 453
michael@0 454 int GonkNativeWindowClient::dispatchSetBuffersDimensions(va_list args) {
michael@0 455 int w = va_arg(args, int);
michael@0 456 int h = va_arg(args, int);
michael@0 457 return setBuffersDimensions(w, h);
michael@0 458 }
michael@0 459
michael@0 460 int GonkNativeWindowClient::dispatchSetBuffersUserDimensions(va_list args) {
michael@0 461 int w = va_arg(args, int);
michael@0 462 int h = va_arg(args, int);
michael@0 463 return setBuffersUserDimensions(w, h);
michael@0 464 }
michael@0 465
michael@0 466 int GonkNativeWindowClient::dispatchSetBuffersFormat(va_list args) {
michael@0 467 int f = va_arg(args, int);
michael@0 468 return setBuffersFormat(f);
michael@0 469 }
michael@0 470
michael@0 471 int GonkNativeWindowClient::dispatchSetScalingMode(va_list args) {
michael@0 472 int m = va_arg(args, int);
michael@0 473 return setScalingMode(m);
michael@0 474 }
michael@0 475
michael@0 476 int GonkNativeWindowClient::dispatchSetBuffersTransform(va_list args) {
michael@0 477 int transform = va_arg(args, int);
michael@0 478 return setBuffersTransform(transform);
michael@0 479 }
michael@0 480
michael@0 481 int GonkNativeWindowClient::dispatchSetBuffersTimestamp(va_list args) {
michael@0 482 int64_t timestamp = va_arg(args, int64_t);
michael@0 483 return setBuffersTimestamp(timestamp);
michael@0 484 }
michael@0 485
michael@0 486 int GonkNativeWindowClient::dispatchLock(va_list args) {
michael@0 487 ANativeWindow_Buffer* outBuffer = va_arg(args, ANativeWindow_Buffer*);
michael@0 488 ARect* inOutDirtyBounds = va_arg(args, ARect*);
michael@0 489 return lock(outBuffer, inOutDirtyBounds);
michael@0 490 }
michael@0 491
michael@0 492 int GonkNativeWindowClient::dispatchUnlockAndPost(va_list args) {
michael@0 493 return unlockAndPost();
michael@0 494 }
michael@0 495
michael@0 496
michael@0 497 int GonkNativeWindowClient::connect(int api) {
michael@0 498 ALOGV("GonkNativeWindowClient::connect");
michael@0 499
michael@0 500 Mutex::Autolock lock(mMutex);
michael@0 501 IGraphicBufferProducer::QueueBufferOutput output;
michael@0 502
michael@0 503 int err = mBufferProducer->connect(api, &output);
michael@0 504 if (err == NO_ERROR) {
michael@0 505 uint32_t numPendingBuffers = 0;
michael@0 506 output.deflate(&mDefaultWidth, &mDefaultHeight, &mTransformHint,
michael@0 507 &numPendingBuffers);
michael@0 508 mConsumerRunningBehind = (numPendingBuffers >= 2);
michael@0 509 }
michael@0 510 if (!err && api == NATIVE_WINDOW_API_CPU) {
michael@0 511 mConnectedToCpu = true;
michael@0 512 }
michael@0 513 return err;
michael@0 514 }
michael@0 515
michael@0 516 int GonkNativeWindowClient::disconnect(int api) {
michael@0 517 ALOGV("GonkNativeWindowClient::disconnect");
michael@0 518 Mutex::Autolock lock(mMutex);
michael@0 519 freeAllBuffers();
michael@0 520 int err = mBufferProducer->disconnect(api);
michael@0 521
michael@0 522 if (!err) {
michael@0 523 mReqFormat = 0;
michael@0 524 mReqWidth = 0;
michael@0 525 mReqHeight = 0;
michael@0 526 mReqUsage = 0;
michael@0 527 mCrop.clear();
michael@0 528 mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
michael@0 529 mTransform = 0;
michael@0 530 if (api == NATIVE_WINDOW_API_CPU) {
michael@0 531 mConnectedToCpu = false;
michael@0 532 }
michael@0 533 }
michael@0 534 return err;
michael@0 535 }
michael@0 536
michael@0 537 int GonkNativeWindowClient::setUsage(uint32_t reqUsage)
michael@0 538 {
michael@0 539 ALOGV("GonkNativeWindowClient::setUsage");
michael@0 540 Mutex::Autolock lock(mMutex);
michael@0 541 mReqUsage = reqUsage;
michael@0 542 return OK;
michael@0 543 }
michael@0 544
michael@0 545 int GonkNativeWindowClient::setCrop(Rect const* rect)
michael@0 546 {
michael@0 547 Rect realRect;
michael@0 548 if (rect == NULL || rect->isEmpty()) {
michael@0 549 realRect.clear();
michael@0 550 } else {
michael@0 551 realRect = *rect;
michael@0 552 }
michael@0 553
michael@0 554 ALOGV("GonkNativeWindowClient::setCrop rect=[%d %d %d %d]",
michael@0 555 realRect.left, realRect.top, realRect.right, realRect.bottom);
michael@0 556
michael@0 557 Mutex::Autolock lock(mMutex);
michael@0 558 mCrop = realRect;
michael@0 559 return NO_ERROR;
michael@0 560 }
michael@0 561
michael@0 562 int GonkNativeWindowClient::setBufferCount(int bufferCount)
michael@0 563 {
michael@0 564 ALOGV("GonkNativeWindowClient::setBufferCount");
michael@0 565 Mutex::Autolock lock(mMutex);
michael@0 566
michael@0 567 status_t err = mBufferProducer->setBufferCount(bufferCount);
michael@0 568 ALOGE_IF(err, "IGraphicBufferProducer::setBufferCount(%d) returned %s",
michael@0 569 bufferCount, strerror(-err));
michael@0 570
michael@0 571 if (err == NO_ERROR) {
michael@0 572 freeAllBuffers();
michael@0 573 }
michael@0 574
michael@0 575 return err;
michael@0 576 }
michael@0 577
michael@0 578 int GonkNativeWindowClient::setBuffersDimensions(int w, int h)
michael@0 579 {
michael@0 580 ALOGV("GonkNativeWindowClient::setBuffersDimensions");
michael@0 581
michael@0 582 if (w<0 || h<0)
michael@0 583 return BAD_VALUE;
michael@0 584
michael@0 585 if ((w && !h) || (!w && h))
michael@0 586 return BAD_VALUE;
michael@0 587
michael@0 588 Mutex::Autolock lock(mMutex);
michael@0 589 mReqWidth = w;
michael@0 590 mReqHeight = h;
michael@0 591 return NO_ERROR;
michael@0 592 }
michael@0 593
michael@0 594 int GonkNativeWindowClient::setBuffersUserDimensions(int w, int h)
michael@0 595 {
michael@0 596 ALOGV("GonkNativeWindowClient::setBuffersUserDimensions");
michael@0 597
michael@0 598 if (w<0 || h<0)
michael@0 599 return BAD_VALUE;
michael@0 600
michael@0 601 if ((w && !h) || (!w && h))
michael@0 602 return BAD_VALUE;
michael@0 603
michael@0 604 Mutex::Autolock lock(mMutex);
michael@0 605 mUserWidth = w;
michael@0 606 mUserHeight = h;
michael@0 607 return NO_ERROR;
michael@0 608 }
michael@0 609
michael@0 610 int GonkNativeWindowClient::setBuffersFormat(int format)
michael@0 611 {
michael@0 612 ALOGV("GonkNativeWindowClient::setBuffersFormat");
michael@0 613
michael@0 614 if (format<0)
michael@0 615 return BAD_VALUE;
michael@0 616
michael@0 617 Mutex::Autolock lock(mMutex);
michael@0 618 mReqFormat = format;
michael@0 619 return NO_ERROR;
michael@0 620 }
michael@0 621
michael@0 622 int GonkNativeWindowClient::setScalingMode(int mode)
michael@0 623 {
michael@0 624 ALOGV("GonkNativeWindowClient::setScalingMode(%d)", mode);
michael@0 625
michael@0 626 switch (mode) {
michael@0 627 case NATIVE_WINDOW_SCALING_MODE_FREEZE:
michael@0 628 case NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW:
michael@0 629 case NATIVE_WINDOW_SCALING_MODE_SCALE_CROP:
michael@0 630 break;
michael@0 631 default:
michael@0 632 ALOGE("unknown scaling mode: %d", mode);
michael@0 633 return BAD_VALUE;
michael@0 634 }
michael@0 635
michael@0 636 Mutex::Autolock lock(mMutex);
michael@0 637 mScalingMode = mode;
michael@0 638 return NO_ERROR;
michael@0 639 }
michael@0 640
michael@0 641 int GonkNativeWindowClient::setBuffersTransform(int transform)
michael@0 642 {
michael@0 643 ALOGV("GonkNativeWindowClient::setBuffersTransform");
michael@0 644 Mutex::Autolock lock(mMutex);
michael@0 645 mTransform = transform;
michael@0 646 return NO_ERROR;
michael@0 647 }
michael@0 648
michael@0 649 int GonkNativeWindowClient::setBuffersTimestamp(int64_t timestamp)
michael@0 650 {
michael@0 651 ALOGV("GonkNativeWindowClient::setBuffersTimestamp");
michael@0 652 Mutex::Autolock lock(mMutex);
michael@0 653 mTimestamp = timestamp;
michael@0 654 return NO_ERROR;
michael@0 655 }
michael@0 656
michael@0 657 void GonkNativeWindowClient::freeAllBuffers() {
michael@0 658 for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
michael@0 659 mSlots[i].buffer = 0;
michael@0 660 }
michael@0 661 }
michael@0 662
michael@0 663 // ----------------------------------------------------------------------
michael@0 664 // the lock/unlock APIs must be used from the same thread
michael@0 665
michael@0 666 // ----------------------------------------------------------------------------
michael@0 667
michael@0 668 status_t GonkNativeWindowClient::lock(
michael@0 669 ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds)
michael@0 670 {
michael@0 671 return INVALID_OPERATION;
michael@0 672 }
michael@0 673
michael@0 674 status_t GonkNativeWindowClient::unlockAndPost()
michael@0 675 {
michael@0 676 return INVALID_OPERATION;
michael@0 677 }
michael@0 678
michael@0 679 }; // namespace android

mercurial