widget/gonk/nativewindow/GonkNativeWindowClientKK.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
-rw-r--r--

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

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

mercurial