Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
1 /*
2 * Copyright (C) 2012 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_NDEBUG 0
19 #define LOG_TAG "GonkNativeWindow"
20 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
21 #include <utils/Log.h>
23 #include "GonkNativeWindowJB.h"
24 #include "GrallocImages.h"
25 #include "mozilla/layers/ImageBridgeChild.h"
26 #include "mozilla/RefPtr.h"
28 #define BI_LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
29 #define BI_LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
30 #define BI_LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
31 #define BI_LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
32 #define BI_LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
34 using namespace mozilla;
35 using namespace mozilla::layers;
37 namespace android {
39 GonkNativeWindow::GonkNativeWindow() :
40 GonkConsumerBase(new GonkBufferQueue(true) )
41 {
42 mBufferQueue->setMaxAcquiredBufferCount(GonkBufferQueue::MIN_UNDEQUEUED_BUFFERS);
43 }
45 GonkNativeWindow::~GonkNativeWindow() {
46 }
48 void GonkNativeWindow::setName(const String8& name) {
49 Mutex::Autolock _l(mMutex);
50 mName = name;
51 mBufferQueue->setConsumerName(name);
52 }
53 #if ANDROID_VERSION >= 18
54 status_t GonkNativeWindow::acquireBuffer(BufferItem *item, bool waitForFence) {
55 status_t err;
57 if (!item) return BAD_VALUE;
59 Mutex::Autolock _l(mMutex);
61 err = acquireBufferLocked(item);
62 if (err != OK) {
63 if (err != NO_BUFFER_AVAILABLE) {
64 BI_LOGE("Error acquiring buffer: %s (%d)", strerror(err), err);
65 }
66 return err;
67 }
69 if (waitForFence) {
70 err = item->mFence->waitForever("GonkNativeWindow::acquireBuffer");
71 if (err != OK) {
72 BI_LOGE("Failed to wait for fence of acquired buffer: %s (%d)",
73 strerror(-err), err);
74 return err;
75 }
76 }
78 item->mGraphicBuffer = mSlots[item->mBuf].mGraphicBuffer;
80 return OK;
81 }
83 status_t GonkNativeWindow::releaseBuffer(const BufferItem &item,
84 const sp<Fence>& releaseFence) {
85 status_t err;
87 Mutex::Autolock _l(mMutex);
89 err = addReleaseFenceLocked(item.mBuf, releaseFence);
91 err = releaseBufferLocked(item.mBuf);
92 if (err != OK) {
93 BI_LOGE("Failed to release buffer: %s (%d)",
94 strerror(-err), err);
95 }
96 return err;
97 }
98 #endif
100 status_t GonkNativeWindow::setDefaultBufferSize(uint32_t w, uint32_t h) {
101 Mutex::Autolock _l(mMutex);
102 return mBufferQueue->setDefaultBufferSize(w, h);
103 }
105 status_t GonkNativeWindow::setDefaultBufferFormat(uint32_t defaultFormat) {
106 Mutex::Autolock _l(mMutex);
107 return mBufferQueue->setDefaultBufferFormat(defaultFormat);
108 }
110 TemporaryRef<TextureClient>
111 GonkNativeWindow::getCurrentBuffer() {
112 Mutex::Autolock _l(mMutex);
113 GonkBufferQueue::BufferItem item;
115 // In asynchronous mode the list is guaranteed to be one buffer
116 // deep, while in synchronous mode we use the oldest buffer.
117 status_t err = acquireBufferLocked(&item);
118 if (err != NO_ERROR) {
119 return NULL;
120 }
122 RefPtr<TextureClient> textureClient =
123 mBufferQueue->getTextureClientFromBuffer(item.mGraphicBuffer.get());
124 if (!textureClient) {
125 return NULL;
126 }
127 textureClient->SetRecycleCallback(GonkNativeWindow::RecycleCallback, this);
128 return textureClient;
129 }
131 /* static */ void
132 GonkNativeWindow::RecycleCallback(TextureClient* client, void* closure) {
133 GonkNativeWindow* nativeWindow =
134 static_cast<GonkNativeWindow*>(closure);
136 client->ClearRecycleCallback();
137 nativeWindow->returnBuffer(client);
138 }
140 void GonkNativeWindow::returnBuffer(TextureClient* client) {
141 BI_LOGD("GonkNativeWindow::returnBuffer");
142 Mutex::Autolock lock(mMutex);
144 int index = mBufferQueue->getSlotFromTextureClientLocked(client);
145 if (index < 0) {
146 }
148 sp<Fence> fence = client->GetReleaseFenceHandle().mFence;
149 if (!fence.get()) {
150 fence = Fence::NO_FENCE;
151 }
153 status_t err;
154 err = addReleaseFenceLocked(index, fence);
156 err = releaseBufferLocked(index);
157 }
159 TemporaryRef<TextureClient>
160 GonkNativeWindow::getTextureClientFromBuffer(ANativeWindowBuffer* buffer) {
161 Mutex::Autolock lock(mMutex);
162 return mBufferQueue->getTextureClientFromBuffer(buffer);
163 }
165 void GonkNativeWindow::setNewFrameCallback(
166 GonkNativeWindowNewFrameCallback* callback) {
167 BI_LOGD("setNewFrameCallback");
168 Mutex::Autolock lock(mMutex);
169 mNewFrameCallback = callback;
170 }
172 void GonkNativeWindow::onFrameAvailable() {
173 GonkConsumerBase::onFrameAvailable();
175 if (mNewFrameCallback) {
176 mNewFrameCallback->OnNewFrame();
177 }
178 }
180 } // namespace android