widget/gonk/nativewindow/GonkNativeWindowClientICS.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) 2012 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 #include "base/basictypes.h"
    20 #include "CameraCommon.h"
    21 #include "GonkNativeWindow.h"
    22 #include "GonkNativeWindowClient.h"
    23 #include "nsDebug.h"
    25 /**
    26  * DOM_CAMERA_LOGI() is enabled in debug builds, and turned on by setting
    27  * NSPR_LOG_MODULES=Camera:N environment variable, where N >= 3.
    28  *
    29  * CNW_LOGE() is always enabled.
    30  */
    31 #define CNW_LOGD(...)   DOM_CAMERA_LOGI(__VA_ARGS__)
    32 #define CNW_LOGE(...)   {(void)printf_stderr(__VA_ARGS__);}
    34 using namespace android;
    35 using namespace mozilla::layers;
    37 GonkNativeWindowClient::GonkNativeWindowClient(const sp<GonkNativeWindow>& window)
    38   : mNativeWindow(window) {
    39     GonkNativeWindowClient::init();
    40 }
    42 GonkNativeWindowClient::~GonkNativeWindowClient() {
    43     if (mConnectedToCpu) {
    44         GonkNativeWindowClient::disconnect(NATIVE_WINDOW_API_CPU);
    45     }
    46 }
    48 void GonkNativeWindowClient::init() {
    49     // Initialize the ANativeWindow function pointers.
    50     ANativeWindow::setSwapInterval  = hook_setSwapInterval;
    51     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;
    52     ANativeWindow::cancelBuffer     = hook_cancelBuffer;
    53     ANativeWindow::lockBuffer       = hook_lockBuffer;
    54     ANativeWindow::queueBuffer      = hook_queueBuffer;
    55     ANativeWindow::query            = hook_query;
    56     ANativeWindow::perform          = hook_perform;
    58     mReqWidth = 0;
    59     mReqHeight = 0;
    60     mReqFormat = 0;
    61     mReqUsage = 0;
    62     mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
    63     mDefaultWidth = 0;
    64     mDefaultHeight = 0;
    65     mTransformHint = 0;
    66     mConnectedToCpu = false;
    67 }
    70 int GonkNativeWindowClient::hook_setSwapInterval(ANativeWindow* window, int interval) {
    71     GonkNativeWindowClient* c = getSelf(window);
    72     return c->setSwapInterval(interval);
    73 }
    75 int GonkNativeWindowClient::hook_dequeueBuffer(ANativeWindow* window,
    76         ANativeWindowBuffer** buffer) {
    77     GonkNativeWindowClient* c = getSelf(window);
    78     return c->dequeueBuffer(buffer);
    79 }
    81 int GonkNativeWindowClient::hook_cancelBuffer(ANativeWindow* window,
    82         ANativeWindowBuffer* buffer) {
    83     GonkNativeWindowClient* c = getSelf(window);
    84     return c->cancelBuffer(buffer);
    85 }
    87 int GonkNativeWindowClient::hook_lockBuffer(ANativeWindow* window,
    88         ANativeWindowBuffer* buffer) {
    89     GonkNativeWindowClient* c = getSelf(window);
    90     return c->lockBuffer(buffer);
    91 }
    93 int GonkNativeWindowClient::hook_queueBuffer(ANativeWindow* window,
    94         ANativeWindowBuffer* buffer) {
    95     GonkNativeWindowClient* c = getSelf(window);
    96     return c->queueBuffer(buffer);
    97 }
    99 int GonkNativeWindowClient::hook_query(const ANativeWindow* window,
   100                                 int what, int* value) {
   101     const GonkNativeWindowClient* c = getSelf(window);
   102     return c->query(what, value);
   103 }
   105 int GonkNativeWindowClient::hook_perform(ANativeWindow* window, int operation, ...) {
   106     va_list args;
   107     va_start(args, operation);
   108     GonkNativeWindowClient* c = getSelf(window);
   109     return c->perform(operation, args);
   110 }
   112 int GonkNativeWindowClient::setSwapInterval(int interval) {
   113     return NO_ERROR;
   114 }
   116 int GonkNativeWindowClient::dequeueBuffer(android_native_buffer_t** buffer) {
   117     CNW_LOGD("GonkNativeWindowClient::dequeueBuffer");
   118     Mutex::Autolock lock(mMutex);
   119     int buf = -1;
   120     status_t result = mNativeWindow->dequeueBuffer(&buf, mReqWidth, mReqHeight,
   121             mReqFormat, mReqUsage);
   122     if (result < 0) {
   123         CNW_LOGD("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
   124              "failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
   125              result);
   126         return result;
   127     }
   128     sp<GraphicBuffer>& gbuf(mSlots[buf]);
   129     if (result & ISurfaceTexture::RELEASE_ALL_BUFFERS) {
   130         freeAllBuffers();
   131     }
   133     if ((result & ISurfaceTexture::BUFFER_NEEDS_REALLOCATION) || gbuf == 0) {
   134         result = mNativeWindow->requestBuffer(buf, &gbuf);
   135         if (result != NO_ERROR) {
   136             CNW_LOGE("dequeueBuffer: ISurfaceTexture::requestBuffer failed: %d",
   137                     result);
   138             return result;
   139         }
   140     }
   141     *buffer = gbuf.get();
   142     return OK;
   143 }
   145 int GonkNativeWindowClient::cancelBuffer(ANativeWindowBuffer* buffer) {
   146     CNW_LOGD("GonkNativeWindowClient::cancelBuffer");
   147     Mutex::Autolock lock(mMutex);
   148     int i = getSlotFromBufferLocked(buffer);
   149     if (i < 0) {
   150         return i;
   151     }
   152     mNativeWindow->cancelBuffer(i);
   153     return OK;
   154 }
   156 int GonkNativeWindowClient::getSlotFromBufferLocked(
   157         android_native_buffer_t* buffer) const {
   158     bool dumpedState = false;
   159     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
   160         // XXX: Dump the slots whenever we hit a NULL entry while searching for
   161         // a buffer.
   162         if (mSlots[i] == NULL) {
   163             if (!dumpedState) {
   164                 CNW_LOGD("getSlotFromBufferLocked: encountered NULL buffer in slot %d "
   165                         "looking for buffer %p", i, buffer->handle);
   166                 for (int j = 0; j < NUM_BUFFER_SLOTS; j++) {
   167                     if (mSlots[j] == NULL) {
   168                         CNW_LOGD("getSlotFromBufferLocked:   %02d: NULL", j);
   169                     } else {
   170                         CNW_LOGD("getSlotFromBufferLocked:   %02d: %p", j, mSlots[j]->handle);
   171                     }
   172                 }
   173                 dumpedState = true;
   174             }
   175         }
   177         if (mSlots[i] != NULL && mSlots[i]->handle == buffer->handle) {
   178             return i;
   179         }
   180     }
   181     CNW_LOGE("getSlotFromBufferLocked: unknown buffer: %p", buffer->handle);
   182     return BAD_VALUE;
   183 }
   186 int GonkNativeWindowClient::lockBuffer(android_native_buffer_t* buffer) {
   187     CNW_LOGD("GonkNativeWindowClient::lockBuffer");
   188     Mutex::Autolock lock(mMutex);
   189     return OK;
   190 }
   192 int GonkNativeWindowClient::queueBuffer(android_native_buffer_t* buffer) {
   193     CNW_LOGD("GonkNativeWindowClient::queueBuffer");
   194     Mutex::Autolock lock(mMutex);
   195     int64_t timestamp;
   196     if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
   197         timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
   198         CNW_LOGD("GonkNativeWindowClient::queueBuffer making up timestamp: %.2f ms",
   199              timestamp / 1000000.f);
   200     } else {
   201         timestamp = mTimestamp;
   202     }
   203     int i = getSlotFromBufferLocked(buffer);
   204     if (i < 0) {
   205         return i;
   206     }
   207     status_t err = mNativeWindow->queueBuffer(i, timestamp,
   208             &mDefaultWidth, &mDefaultHeight, &mTransformHint);
   209     if (err != OK)  {
   210         CNW_LOGE("queueBuffer: error queuing buffer to GonkNativeWindow, %d", err);
   211     }
   212     return err;
   213 }
   215 int GonkNativeWindowClient::query(int what, int* value) const {
   216     CNW_LOGD("query");
   217     { // scope for the lock
   218         Mutex::Autolock lock(mMutex);
   219         switch (what) {
   220             case NATIVE_WINDOW_FORMAT:
   221                 if (mReqFormat) {
   222                     *value = mReqFormat;
   223                     return NO_ERROR;
   224                 }
   225                 break;
   226             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
   227                 *value = 0;
   228                 return NO_ERROR;
   229             case NATIVE_WINDOW_CONCRETE_TYPE:
   230                 *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
   231                 return NO_ERROR;
   232             case NATIVE_WINDOW_DEFAULT_WIDTH:
   233                 *value = mDefaultWidth;
   234                 return NO_ERROR;
   235             case NATIVE_WINDOW_DEFAULT_HEIGHT:
   236                 *value = mDefaultHeight;
   237                 return NO_ERROR;
   238             case NATIVE_WINDOW_TRANSFORM_HINT:
   239                 *value = mTransformHint;
   240                 return NO_ERROR;
   241         }
   242     }
   243     return mNativeWindow->query(what, value);
   244 }
   246 int GonkNativeWindowClient::perform(int operation, va_list args)
   247 {
   248     int res = NO_ERROR;
   249     switch (operation) {
   250     case NATIVE_WINDOW_CONNECT:
   251         // deprecated. must return NO_ERROR.
   252         break;
   253     case NATIVE_WINDOW_DISCONNECT:
   254         // deprecated. must return NO_ERROR.
   255         break;
   256     case NATIVE_WINDOW_SET_SCALING_MODE:
   257         return NO_ERROR;
   258     case NATIVE_WINDOW_SET_USAGE:
   259         res = dispatchSetUsage(args);
   260         break;
   261     case NATIVE_WINDOW_SET_CROP:
   262         //not implemented
   263         break;
   264     case NATIVE_WINDOW_SET_BUFFER_COUNT:
   265         res = dispatchSetBufferCount(args);
   266         break;
   267     case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
   268         res = dispatchSetBuffersGeometry(args);
   269         break;
   270     case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
   271         //not implemented
   272         break;
   273     case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP:
   274         res = dispatchSetBuffersTimestamp(args);
   275         break;
   276     case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS:
   277         res = dispatchSetBuffersDimensions(args);
   278         break;
   279     case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
   280         res = dispatchSetBuffersFormat(args);
   281         break;
   282     case NATIVE_WINDOW_LOCK:
   283         res = INVALID_OPERATION;// not supported
   284         break;
   285     case NATIVE_WINDOW_UNLOCK_AND_POST:
   286         res = INVALID_OPERATION;// not supported
   287         break;
   288     case NATIVE_WINDOW_API_CONNECT:
   289         res = dispatchConnect(args);
   290         break;
   291     case NATIVE_WINDOW_API_DISCONNECT:
   292         res = dispatchDisconnect(args);
   293         break;
   294     case NATIVE_WINDOW_SET_BUFFERS_SIZE:
   295         //not implemented
   296         break;
   297     default:
   298         res = NAME_NOT_FOUND;
   299         break;
   300     }
   301     return res;
   302 }
   304 int GonkNativeWindowClient::dispatchConnect(va_list args) {
   305     int api = va_arg(args, int);
   306     return connect(api);
   307 }
   309 int GonkNativeWindowClient::dispatchDisconnect(va_list args) {
   310     int api = va_arg(args, int);
   311     return disconnect(api);
   312 }
   314 int GonkNativeWindowClient::dispatchSetUsage(va_list args) {
   315     int usage = va_arg(args, int);
   316     return setUsage(usage);
   317 }
   319 int GonkNativeWindowClient::dispatchSetBufferCount(va_list args) {
   320     size_t bufferCount = va_arg(args, size_t);
   321     return setBufferCount(bufferCount);
   322 }
   324 int GonkNativeWindowClient::dispatchSetBuffersGeometry(va_list args) {
   325     int w = va_arg(args, int);
   326     int h = va_arg(args, int);
   327     int f = va_arg(args, int);
   328     int err = setBuffersDimensions(w, h);
   329     if (err != 0) {
   330         return err;
   331     }
   332     return setBuffersFormat(f);
   333 }
   335 int GonkNativeWindowClient::dispatchSetBuffersDimensions(va_list args) {
   336     int w = va_arg(args, int);
   337     int h = va_arg(args, int);
   338     return setBuffersDimensions(w, h);
   339 }
   341 int GonkNativeWindowClient::dispatchSetBuffersFormat(va_list args) {
   342     int f = va_arg(args, int);
   343     return setBuffersFormat(f);
   344 }
   346 int GonkNativeWindowClient::dispatchSetBuffersTimestamp(va_list args) {
   347     int64_t timestamp = va_arg(args, int64_t);
   348     return setBuffersTimestamp(timestamp);
   349 }
   351 int GonkNativeWindowClient::connect(int api) {
   352     CNW_LOGD("GonkNativeWindowClient::connect");
   353     Mutex::Autolock lock(mMutex);
   354     int err = mNativeWindow->connect(api,
   355             &mDefaultWidth, &mDefaultHeight, &mTransformHint);
   356     if (!err && api == NATIVE_WINDOW_API_CPU) {
   357         mConnectedToCpu = true;
   358     }
   359     return err;
   360 }
   362 int GonkNativeWindowClient::disconnect(int api) {
   363     CNW_LOGD("GonkNativeWindowClient::disconnect");
   364     Mutex::Autolock lock(mMutex);
   365     freeAllBuffers();
   366     int err = mNativeWindow->disconnect(api);
   367     if (!err) {
   368         mReqFormat = 0;
   369         mReqWidth = 0;
   370         mReqHeight = 0;
   371         mReqUsage = 0;
   372         if (api == NATIVE_WINDOW_API_CPU) {
   373             mConnectedToCpu = false;
   374         }
   375     }
   376     return err;
   377 }
   379 int GonkNativeWindowClient::setUsage(uint32_t reqUsage)
   380 {
   381     CNW_LOGD("GonkNativeWindowClient::setUsage");
   382     Mutex::Autolock lock(mMutex);
   383     mReqUsage = reqUsage;
   384     return OK;
   385 }
   387 int GonkNativeWindowClient::setBufferCount(int bufferCount)
   388 {
   389     CNW_LOGD("GonkNativeWindowClient::setBufferCount");
   390     Mutex::Autolock lock(mMutex);
   392     status_t err = mNativeWindow->setBufferCount(bufferCount);
   393     if (err == NO_ERROR) {
   394         freeAllBuffers();
   395     }
   397     return err;
   398 }
   400 int GonkNativeWindowClient::setBuffersDimensions(int w, int h)
   401 {
   402     CNW_LOGD("GonkNativeWindowClient::setBuffersDimensions");
   403     Mutex::Autolock lock(mMutex);
   405     if (w<0 || h<0)
   406         return BAD_VALUE;
   408     if ((w && !h) || (!w && h))
   409         return BAD_VALUE;
   411     mReqWidth = w;
   412     mReqHeight = h;
   414     status_t err = OK;
   416     return err;
   417 }
   419 int GonkNativeWindowClient::setBuffersFormat(int format)
   420 {
   421     CNW_LOGD("GonkNativeWindowClient::setBuffersFormat");
   422     Mutex::Autolock lock(mMutex);
   424     if (format<0)
   425         return BAD_VALUE;
   427     mReqFormat = format;
   429     return NO_ERROR;
   430 }
   433 int GonkNativeWindowClient::setBuffersTimestamp(int64_t timestamp)
   434 {
   435     CNW_LOGD("GonkNativeWindowClient::setBuffersTimestamp");
   436     Mutex::Autolock lock(mMutex);
   437     mTimestamp = timestamp;
   438     return NO_ERROR;
   439 }
   441 void GonkNativeWindowClient::freeAllBuffers() {
   442     for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
   443         mSlots[i] = 0;
   444     }
   445 }

mercurial