1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/widget/gonk/nativewindow/GonkNativeWindowKK.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,188 @@ 1.4 +/* 1.5 + * Copyright (C) 2012 The Android Open Source Project 1.6 + * Copyright (C) 2013 Mozilla Foundation 1.7 + * 1.8 + * Licensed under the Apache License, Version 2.0 (the "License"); 1.9 + * you may not use this file except in compliance with the License. 1.10 + * You may obtain a copy of the License at 1.11 + * 1.12 + * http://www.apache.org/licenses/LICENSE-2.0 1.13 + * 1.14 + * Unless required by applicable law or agreed to in writing, software 1.15 + * distributed under the License is distributed on an "AS IS" BASIS, 1.16 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.17 + * See the License for the specific language governing permissions and 1.18 + * limitations under the License. 1.19 + */ 1.20 + 1.21 +//#define LOG_NDEBUG 0 1.22 +#define LOG_TAG "GonkNativeWindow" 1.23 +#define ATRACE_TAG ATRACE_TAG_GRAPHICS 1.24 +#include <utils/Log.h> 1.25 + 1.26 +#include "GonkNativeWindowKK.h" 1.27 +#include "GrallocImages.h" 1.28 + 1.29 +#define BI_LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__) 1.30 +#define BI_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) 1.31 +#define BI_LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 1.32 +#define BI_LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) 1.33 +#define BI_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 1.34 + 1.35 +using namespace mozilla; 1.36 +using namespace mozilla::layers; 1.37 + 1.38 +namespace android { 1.39 + 1.40 +GonkNativeWindow::GonkNativeWindow() : 1.41 + GonkConsumerBase(new GonkBufferQueue(true), false) 1.42 +{ 1.43 + mConsumer->setMaxAcquiredBufferCount(GonkBufferQueue::MIN_UNDEQUEUED_BUFFERS); 1.44 +} 1.45 + 1.46 +GonkNativeWindow::GonkNativeWindow(const sp<GonkBufferQueue>& bq, 1.47 + uint32_t consumerUsage, int bufferCount, bool controlledByApp) : 1.48 + GonkConsumerBase(bq, controlledByApp) 1.49 +{ 1.50 + mConsumer->setConsumerUsageBits(consumerUsage); 1.51 + mConsumer->setMaxAcquiredBufferCount(bufferCount); 1.52 +} 1.53 + 1.54 +GonkNativeWindow::~GonkNativeWindow() { 1.55 +} 1.56 + 1.57 +void GonkNativeWindow::setName(const String8& name) { 1.58 + Mutex::Autolock _l(mMutex); 1.59 + mName = name; 1.60 + mConsumer->setConsumerName(name); 1.61 +} 1.62 + 1.63 +status_t GonkNativeWindow::acquireBuffer(BufferItem *item, 1.64 + nsecs_t presentWhen, bool waitForFence) { 1.65 + status_t err; 1.66 + 1.67 + if (!item) return BAD_VALUE; 1.68 + 1.69 + Mutex::Autolock _l(mMutex); 1.70 + 1.71 + err = acquireBufferLocked(item, presentWhen); 1.72 + if (err != OK) { 1.73 + if (err != NO_BUFFER_AVAILABLE) { 1.74 + BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err); 1.75 + } 1.76 + return err; 1.77 + } 1.78 + 1.79 + if (waitForFence) { 1.80 + err = item->mFence->waitForever("GonkNativeWindow::acquireBuffer"); 1.81 + if (err != OK) { 1.82 + BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)", 1.83 + strerror(-err), err); 1.84 + return err; 1.85 + } 1.86 + } 1.87 + 1.88 + item->mGraphicBuffer = mSlots[item->mBuf].mGraphicBuffer; 1.89 + 1.90 + return OK; 1.91 +} 1.92 + 1.93 +status_t GonkNativeWindow::releaseBuffer(const BufferItem &item, 1.94 + const sp<Fence>& releaseFence) { 1.95 + status_t err; 1.96 + 1.97 + Mutex::Autolock _l(mMutex); 1.98 + 1.99 + err = addReleaseFenceLocked(item.mBuf, item.mGraphicBuffer, releaseFence); 1.100 + 1.101 + err = releaseBufferLocked(item.mBuf, item.mGraphicBuffer); 1.102 + if (err != OK) { 1.103 + BI_LOGE("Failed to release buffer: %s (%d)", 1.104 + strerror(-err), err); 1.105 + } 1.106 + return err; 1.107 +} 1.108 + 1.109 +status_t GonkNativeWindow::setDefaultBufferSize(uint32_t w, uint32_t h) { 1.110 + Mutex::Autolock _l(mMutex); 1.111 + return mConsumer->setDefaultBufferSize(w, h); 1.112 +} 1.113 + 1.114 +status_t GonkNativeWindow::setDefaultBufferFormat(uint32_t defaultFormat) { 1.115 + Mutex::Autolock _l(mMutex); 1.116 + return mConsumer->setDefaultBufferFormat(defaultFormat); 1.117 +} 1.118 + 1.119 +TemporaryRef<TextureClient> 1.120 +GonkNativeWindow::getCurrentBuffer() { 1.121 + Mutex::Autolock _l(mMutex); 1.122 + BufferItem item; 1.123 + 1.124 + // In asynchronous mode the list is guaranteed to be one buffer 1.125 + // deep, while in synchronous mode we use the oldest buffer. 1.126 + status_t err = acquireBufferLocked(&item, 0); //??? 1.127 + if (err != NO_ERROR) { 1.128 + return NULL; 1.129 + } 1.130 + 1.131 + RefPtr<TextureClient> textureClient = 1.132 + mConsumer->getTextureClientFromBuffer(item.mGraphicBuffer.get()); 1.133 + if (!textureClient) { 1.134 + return NULL; 1.135 + } 1.136 + textureClient->SetRecycleCallback(GonkNativeWindow::RecycleCallback, this); 1.137 + return textureClient; 1.138 +} 1.139 + 1.140 +/* static */ void 1.141 +GonkNativeWindow::RecycleCallback(TextureClient* client, void* closure) { 1.142 + GonkNativeWindow* nativeWindow = 1.143 + static_cast<GonkNativeWindow*>(closure); 1.144 + 1.145 + client->ClearRecycleCallback(); 1.146 + nativeWindow->returnBuffer(client); 1.147 +} 1.148 + 1.149 +void GonkNativeWindow::returnBuffer(TextureClient* client) { 1.150 + BI_LOGD("GonkNativeWindow::returnBuffer"); 1.151 + Mutex::Autolock lock(mMutex); 1.152 + 1.153 + int index = mConsumer->getSlotFromTextureClientLocked(client); 1.154 + if (index < 0) { 1.155 + } 1.156 + 1.157 + sp<Fence> fence = client->GetReleaseFenceHandle().mFence; 1.158 + if (!fence.get()) { 1.159 + fence = Fence::NO_FENCE; 1.160 + } 1.161 + 1.162 + status_t err; 1.163 + err = addReleaseFenceLocked(index, 1.164 + mSlots[index].mGraphicBuffer, 1.165 + fence); 1.166 + 1.167 + err = releaseBufferLocked(index, mSlots[index].mGraphicBuffer); 1.168 +} 1.169 + 1.170 +TemporaryRef<TextureClient> 1.171 +GonkNativeWindow::getTextureClientFromBuffer(ANativeWindowBuffer* buffer) { 1.172 + Mutex::Autolock lock(mMutex); 1.173 + return mConsumer->getTextureClientFromBuffer(buffer); 1.174 +} 1.175 + 1.176 +void GonkNativeWindow::setNewFrameCallback( 1.177 + GonkNativeWindowNewFrameCallback* callback) { 1.178 + BI_LOGD("setNewFrameCallback"); 1.179 + Mutex::Autolock lock(mMutex); 1.180 + mNewFrameCallback = callback; 1.181 +} 1.182 + 1.183 +void GonkNativeWindow::onFrameAvailable() { 1.184 + GonkConsumerBase::onFrameAvailable(); 1.185 + 1.186 + if (mNewFrameCallback) { 1.187 + mNewFrameCallback->OnNewFrame(); 1.188 + } 1.189 +} 1.190 + 1.191 +} // namespace android