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

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

mercurial