widget/gonk/nativewindow/GonkNativeWindowClientKK.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial