android_hardware_qcom_display/libhwcomposer/hwc_qbuf.h
Saurabh Shah 1be2fcd4f0 hwc: qbuf: Add API to unlock all
Add API to unlock all current and previous buffers.
This is essential in suspend cases.

CRs-fixed: 382332

(cherry picked from commit d24eb9e70480f89561108078f68cbbd9b20e4bb5)

Change-Id: I54fcded7cabc79d991d4b28a248867d860ec6b08
2012-09-12 22:52:42 -05:00

128 lines
3.8 KiB
C++

/*
* Copyright (C) 2010 The Android Open Source Project
* Copyright (C) 2012, Code Aurora Forum. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gralloc_priv.h>
#include <genlock.h>
// -----------------------------------------------------------------------------
// QueuedBufferStore
//This class holds currently and previously queued buffers.
//Provides utilities to store, lock, remove, unlock.
namespace qhwc{
static const int MAX_QUEUED_BUFS = 4;
class QueuedBufferStore {
public:
QueuedBufferStore() {
clearCurrent();
clearPrevious();
}
~QueuedBufferStore() {}
void lockAndAdd(private_handle_t*);
//Unlocks only previous and makes the current as previous
void unlockAllPrevious();
//Unlocks previous as well as current, useful in suspend case
void unlockAll();
private:
QueuedBufferStore& operator=(const QueuedBufferStore&);
QueuedBufferStore(const QueuedBufferStore&);
bool lockBuffer(private_handle_t *hnd);
void unlockBuffer(private_handle_t *hnd);
void clearCurrent();
void clearPrevious();
void mvCurrToPrev();
//members
private_handle_t *current[MAX_QUEUED_BUFS]; //holds buf being queued
private_handle_t *previous[MAX_QUEUED_BUFS]; //holds bufs queued in prev round
int curCount;
int prevCount;
};
//Store and lock current drawing round buffers
inline void QueuedBufferStore::lockAndAdd(private_handle_t *hnd) {
if(lockBuffer(hnd))
current[curCount++] = hnd;
}
//Unlock all previous drawing round buffers
inline void QueuedBufferStore::unlockAllPrevious() {
//Unlock
for(int i = 0; i < prevCount; i++) {
unlockBuffer(previous[i]);
previous[i] = NULL;
}
//Move current hnd to previous
mvCurrToPrev();
//Clear current
clearCurrent();
}
inline void QueuedBufferStore::unlockAll() {
//Unlocks prev and moves current to prev
unlockAllPrevious();
//Unlocks the newly populated prev if any.
unlockAllPrevious();
}
//Clear currentbuf store
inline void QueuedBufferStore::clearCurrent() {
for(int i = 0; i < MAX_QUEUED_BUFS; i++)
current[i] = NULL;
curCount = 0;
}
//Clear previousbuf store
inline void QueuedBufferStore::clearPrevious() {
for(int i = 0; i < MAX_QUEUED_BUFS; i++)
previous[i] = NULL;
prevCount = 0;
}
//Copy from current to previous
inline void QueuedBufferStore::mvCurrToPrev() {
for(int i = 0; i < curCount; i++)
previous[i] = current[i];
prevCount = curCount;
}
inline bool QueuedBufferStore::lockBuffer(private_handle_t *hnd) {
if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
GENLOCK_MAX_TIMEOUT)) {
ALOGE("%s: genlock_lock_buffer(READ) failed", __func__);
return false;
}
return true;
}
inline void QueuedBufferStore::unlockBuffer(private_handle_t *hnd) {
//Check if buffer is still around
if(private_handle_t::validate(hnd) != 0) {
ALOGE("%s Invalid Handle", __func__);
return;
}
//Actually try to unlock
if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
ALOGE("%s: genlock_unlock_buffer failed", __func__);
return;
}
}
// -----------------------------------------------------------------------------
};//namespace