add support hwc 1.1

Bug: 7124069

Change-Id: I53d705105c4ad8954d3f50ee4f4c8b7ec936b871
This commit is contained in:
Mathias Agopian 2012-09-13 18:17:13 -07:00
parent cde87a3b9d
commit da27af9832
11 changed files with 283 additions and 89 deletions

View File

@ -183,6 +183,32 @@ void DisplayDevice::flip(const Region& dirty) const
mPageFlipCount++;
}
void DisplayDevice::swapBuffers(HWComposer& hwc) const {
if (hwc.initCheck() != NO_ERROR) {
// no HWC, we call eglSwapBuffers()
eglSwapBuffers(mDisplay, mSurface);
} else {
if (hwc.hasGlesComposition(mType)) {
if (hwc.supportsFramebufferTarget() ||
mType >= DisplayDevice::DISPLAY_VIRTUAL) {
// as of hwc 1.1 we always call eglSwapBuffers, however,
// on older versions of HWC, we need to call it only on
// virtual displays
eglSwapBuffers(mDisplay, mSurface);
}
}
}
}
void DisplayDevice::onSwapBuffersCompleted(HWComposer& hwc) const {
if (hwc.initCheck() == NO_ERROR) {
if (hwc.supportsFramebufferTarget()) {
int fd = hwc.getAndResetReleaseFenceFd(mType);
mFramebufferSurface->setReleaseFenceFd(fd);
}
}
}
uint32_t DisplayDevice::getFlags() const
{
return mFlags;

View File

@ -40,6 +40,7 @@ class DisplayInfo;
class FramebufferSurface;
class LayerBase;
class SurfaceFlinger;
class HWComposer;
class DisplayDevice : public LightRefBase<DisplayDevice>
{
@ -106,8 +107,12 @@ public:
int32_t getHwcDisplayId() const { return mHwcDisplayId; }
const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
void swapBuffers(HWComposer& hwc) const;
status_t compositionComplete() const;
// called after h/w composer has completed its set() call
void onSwapBuffersCompleted(HWComposer& hwc) const;
Rect getBounds() const {
return Rect(mDisplayWidth, mDisplayHeight);
}

View File

@ -74,15 +74,13 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc) :
mBufferQueue->setDefaultMaxBufferCount(NUM_FRAME_BUFFERS);
}
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) {
Mutex::Autolock lock(mMutex);
BufferQueue::BufferItem item;
status_t err = acquireBufferLocked(&item);
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
if (buffer != NULL) {
*buffer = mCurrentBuffer;
}
outBuffer = mCurrentBuffer;
return NO_ERROR;
} else if (err != NO_ERROR) {
ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err);
@ -107,32 +105,24 @@ status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>* buffer) {
return err;
}
}
mCurrentBufferSlot = item.mBuf;
mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer;
if (item.mFence != NULL) {
item.mFence->wait(Fence::TIMEOUT_NEVER);
}
if (buffer != NULL) {
*buffer = mCurrentBuffer;
}
outFence = item.mFence;
outBuffer = mCurrentBuffer;
return NO_ERROR;
}
// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl.
void FramebufferSurface::onFrameAvailable() {
// XXX: The following code is here temporarily as part of the transition
// away from the framebuffer HAL.
sp<GraphicBuffer> buf;
status_t err = nextBuffer(&buf);
sp<Fence> acquireFence;
status_t err = nextBuffer(buf, acquireFence);
if (err != NO_ERROR) {
ALOGE("error latching next FramebufferSurface buffer: %s (%d)",
ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)",
strerror(-err), err);
return;
}
err = mHwc.fbPost(buf->handle);
err = mHwc.fbPost(0, acquireFence, buf); // FIXME: use real display id
if (err != NO_ERROR) {
ALOGE("error posting framebuffer: %d", err);
}
@ -145,6 +135,19 @@ void FramebufferSurface::freeBufferLocked(int slotIndex) {
}
}
status_t FramebufferSurface::setReleaseFenceFd(int fenceFd) {
status_t err = NO_ERROR;
if (fenceFd >= 0) {
sp<Fence> fence(new Fence(fenceFd));
if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT) {
status_t err = addReleaseFence(mCurrentBufferSlot, fence);
ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)",
strerror(-err), err);
}
}
return err;
}
status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
{
return INVALID_OPERATION;

View File

@ -44,10 +44,13 @@ public:
virtual void dump(String8& result);
// nextBuffer waits for and then latches the next buffer from the
// BufferQueue and releases the previously latched buffer to the
// BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>* buffer);
// setReleaseFenceFd stores a fence file descriptor that will signal when the
// current buffer is no longer being read. This fence will be returned to
// the producer when the current buffer is released by updateTexImage().
// Multiple fences can be set for a given buffer; they will be merged into
// a single union fence. The SurfaceTexture will close the file descriptor
// when finished with it.
status_t setReleaseFenceFd(int fenceFd);
private:
virtual ~FramebufferSurface() { }; // this class cannot be overloaded
@ -55,6 +58,11 @@ private:
virtual void onFrameAvailable();
virtual void freeBufferLocked(int slotIndex);
// nextBuffer waits for and then latches the next buffer from the
// BufferQueue and releases the previously latched buffer to the
// BufferQueue. The new buffer is returned in the 'buffer' argument.
status_t nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence);
// mCurrentBufferIndex is the slot index of the current buffer or
// INVALID_BUFFER_SLOT to indicate that either there is no current buffer
// or the buffer is not associated with a slot.

View File

@ -26,6 +26,7 @@
#include <sys/types.h>
#include <utils/Errors.h>
#include <utils/misc.h>
#include <utils/String8.h>
#include <utils/Thread.h>
#include <utils/Trace.h>
@ -43,6 +44,7 @@
#include "LayerBase.h"
#include "HWComposer.h"
#include "SurfaceFlinger.h"
#include <utils/CallStack.h>
namespace android {
@ -111,6 +113,14 @@ HWComposer::HWComposer(
loadFbHalModule();
loadHwcModule();
if (mFbDev && mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// close FB HAL if we don't needed it.
// FIXME: this is temporary until we're not forced to open FB HAL
// before HWC.
framebuffer_close(mFbDev);
mFbDev = NULL;
}
// If we have no HWC, or a pre-1.1 HWC, an FB dev is mandatory.
if ((!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
&& !mFbDev) {
@ -310,7 +320,7 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = {
#define ANDROID_DENSITY_XHIGH 320
void HWComposer::queryDisplayProperties(int disp) {
ALOG_ASSERT(mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
// use zero as default value for unspecified attributes
int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
@ -319,7 +329,11 @@ void HWComposer::queryDisplayProperties(int disp) {
uint32_t config;
size_t numConfigs = 1;
status_t err = mHwc->getDisplayConfigs(mHwc, disp, &config, &numConfigs);
LOG_ALWAYS_FATAL_IF(err, "getDisplayAttributes failed (%s)", strerror(-err));
if (err == NO_ERROR) {
ALOGD("config=%d, numConfigs=%d, NUM_DISPLAY_ATTRIBUTES=%d",
config, numConfigs, NUM_DISPLAY_ATTRIBUTES);
mHwc->getDisplayAttributes(mHwc, disp, config, DISPLAY_ATTRIBUTES,
values);
}
@ -343,8 +357,8 @@ void HWComposer::queryDisplayProperties(int disp) {
mDisplayData[disp].ydpi = values[i] / 1000.0f;
break;
default:
ALOG_ASSERT(false, "unknown display attribute %#x",
DISPLAY_ATTRIBUTES[i]);
ALOG_ASSERT(false, "unknown display attribute[%d] %#x",
i, DISPLAY_ATTRIBUTES[i]);
break;
}
}
@ -439,13 +453,35 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
if (mHwc) {
DisplayData& disp(mDisplayData[id]);
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// we need space for the HWC_FRAMEBUFFER_TARGET
numLayers++;
}
if (disp.capacity < numLayers || disp.list == NULL) {
const size_t size = sizeof(hwc_display_contents_1_t)
size_t size = sizeof(hwc_display_contents_1_t)
+ numLayers * sizeof(hwc_layer_1_t);
free(disp.list);
disp.list = (hwc_display_contents_1_t*)malloc(size);
disp.capacity = numLayers;
}
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
disp.framebufferTarget = &disp.list->hwLayers[numLayers - 1];
memset(disp.framebufferTarget, 0, sizeof(hwc_layer_1_t));
const hwc_rect_t r = { 0, 0, disp.width, disp.height };
disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
disp.framebufferTarget->hints = 0;
disp.framebufferTarget->flags = 0;
disp.framebufferTarget->handle = disp.fbTargetHandle;
disp.framebufferTarget->transform = 0;
disp.framebufferTarget->blending = HWC_BLENDING_PREMULT;
disp.framebufferTarget->sourceCrop = r;
disp.framebufferTarget->displayFrame = r;
disp.framebufferTarget->visibleRegionScreen.numRects = 1;
disp.framebufferTarget->visibleRegionScreen.rects =
&disp.framebufferTarget->displayFrame;
disp.framebufferTarget->acquireFenceFd = -1;
disp.framebufferTarget->releaseFenceFd = -1;
}
disp.list->retireFenceFd = -1;
disp.list->flags = HWC_GEOMETRY_CHANGED;
disp.list->numHwLayers = numLayers;
@ -453,9 +489,46 @@ status_t HWComposer::createWorkList(int32_t id, size_t numLayers) {
return NO_ERROR;
}
status_t HWComposer::setFramebufferTarget(int32_t id,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf) {
if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
return BAD_INDEX;
}
DisplayData& disp(mDisplayData[id]);
if (!disp.framebufferTarget) {
// this should never happen, but apparently eglCreateWindowSurface()
// triggers a SurfaceTextureClient::queueBuffer() on some
// devices (!?) -- log and ignore.
ALOGE("HWComposer: framebufferTarget is null");
CallStack stack;
stack.update();
stack.dump("");
return NO_ERROR;
}
int acquireFenceFd = -1;
if (acquireFence != NULL) {
acquireFenceFd = acquireFence->dup();
}
// ALOGD("fbPost: handle=%p, fence=%d", buf->handle, acquireFenceFd);
disp.fbTargetHandle = buf->handle;
disp.framebufferTarget->handle = disp.fbTargetHandle;
disp.framebufferTarget->acquireFenceFd = acquireFenceFd;
return NO_ERROR;
}
status_t HWComposer::prepare() {
for (size_t i=0 ; i<mNumDisplays ; i++) {
mLists[i] = mDisplayData[i].list;
DisplayData& disp(mDisplayData[i]);
if (disp.framebufferTarget) {
// make sure to reset the type to HWC_FRAMEBUFFER_TARGET
// DO NOT reset the handle field to NULL, because it's possible
// that we have nothing to redraw (eg: eglSwapBuffers() not called)
// in which case, we should continue to use the same buffer.
disp.framebufferTarget->compositionType = HWC_FRAMEBUFFER_TARGET;
}
mLists[i] = disp.list;
if (mLists[i]) {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_2)) {
mLists[i]->outbuf = NULL;
@ -472,6 +545,8 @@ status_t HWComposer::prepare() {
}
int err = mHwc->prepare(mHwc, mNumDisplays, mLists);
ALOGE_IF(err, "HWComposer: prepare failed (%s)", strerror(-err));
if (err == NO_ERROR) {
// here we're just making sure that "skip" layers are set
// to HWC_FRAMEBUFFER and we're also counting how many layers
@ -483,6 +558,10 @@ status_t HWComposer::prepare() {
if (disp.list) {
for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
hwc_layer_1_t& l = disp.list->hwLayers[i];
//ALOGD("prepare: %d, type=%d, handle=%p",
// i, l.compositionType, l.handle);
if (l.flags & HWC_SKIP_LAYER) {
l.compositionType = HWC_FRAMEBUFFER;
}
@ -511,6 +590,21 @@ bool HWComposer::hasGlesComposition(int32_t id) const {
return mDisplayData[id].hasFbComp;
}
int HWComposer::getAndResetReleaseFenceFd(int32_t id) {
if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id))
return BAD_INDEX;
int fd = INVALID_OPERATION;
if (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
const DisplayData& disp(mDisplayData[id]);
if (disp.framebufferTarget) {
fd = disp.framebufferTarget->releaseFenceFd;
disp.framebufferTarget->releaseFenceFd = -1;
}
}
return fd;
}
status_t HWComposer::commit() {
int err = NO_ERROR;
if (mHwc) {
@ -553,38 +647,43 @@ status_t HWComposer::acquire() const {
return NO_ERROR;
}
size_t HWComposer::getNumLayers(int32_t id) const {
if (uint32_t(id)>31 || !mAllocatedDisplayIDs.hasBit(id)) {
return 0;
}
return (mHwc && mDisplayData[id].list) ?
mDisplayData[id].list->numHwLayers : 0;
}
int HWComposer::getVisualID() const {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
// is supported by the implementation. we can only be in this case
// if we have HWC 1.1
return HAL_PIXEL_FORMAT_RGBA_8888;
//return HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
} else {
return mFbDev->format;
}
}
int HWComposer::fbPost(buffer_handle_t buffer) {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
return mFbDev->post(mFbDev, buffer);
bool HWComposer::supportsFramebufferTarget() const {
return (mHwc && hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1));
}
int HWComposer::fbPost(int32_t id,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buffer) {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
return setFramebufferTarget(id, acquireFence, buffer);
} else {
if (acquireFence != NULL) {
acquireFence->wait(Fence::TIMEOUT_NEVER);
}
return mFbDev->post(mFbDev, buffer->handle);
}
return NO_ERROR;
}
int HWComposer::fbCompositionComplete() {
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_0)) {
if (mFbDev->compositionComplete) {
return mFbDev->compositionComplete(mFbDev);
} else {
return INVALID_OPERATION;
}
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1))
return NO_ERROR;
if (mFbDev->compositionComplete) {
return mFbDev->compositionComplete(mFbDev);
} else {
return INVALID_OPERATION;
}
return NO_ERROR;
}
void HWComposer::fbDump(String8& result) {
@ -596,7 +695,6 @@ void HWComposer::fbDump(String8& result) {
}
}
/*
* Helper template to implement a concrete HWCLayer
* This holds the pointer to the concrete hwc layer type
@ -733,7 +831,22 @@ HWComposer::LayerListIterator HWComposer::begin(int32_t id) {
* returns an iterator on the end of the layer list
*/
HWComposer::LayerListIterator HWComposer::end(int32_t id) {
return getLayerIterator(id, getNumLayers(id));
size_t numLayers = 0;
if (uint32_t(id) <= 31 && mAllocatedDisplayIDs.hasBit(id)) {
const DisplayData& disp(mDisplayData[id]);
if (mHwc && disp.list) {
numLayers = disp.list->numHwLayers;
if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)) {
// with HWC 1.1, the last layer is always the HWC_FRAMEBUFFER_TARGET,
// which we ignore when iterating through the layer list.
ALOGE_IF(!numLayers, "mDisplayData[%d].list->numHwLayers is 0", id);
if (numLayers) {
numLayers--;
}
}
}
}
return getLayerIterator(id, numLayers);
}
void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
@ -747,27 +860,47 @@ void HWComposer::dump(String8& result, char* buffer, size_t SIZE,
result.appendFormat(" id=%d, numHwLayers=%u, flags=%08x\n",
i, disp.list->numHwLayers, disp.list->flags);
result.append(
" type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
"----------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
// " ________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
" type | handle | hints | flags | tr | blend | format | source crop | frame name \n"
"------------+----------+----------+----------+----+-------+----------+---------------------------+--------------------------------\n");
// " __________ | ________ | ________ | ________ | __ | _____ | ________ | [_____,_____,_____,_____] | [_____,_____,_____,_____]
for (size_t i=0 ; i<disp.list->numHwLayers ; i++) {
const hwc_layer_1_t&l = disp.list->hwLayers[i];
const sp<LayerBase> layer(visibleLayersSortedByZ[i]);
int32_t format = -1;
if (layer->getLayer() != NULL) {
const sp<GraphicBuffer>& buffer(
String8 name("unknown");
if (i < visibleLayersSortedByZ.size()) {
const sp<LayerBase>& layer(visibleLayersSortedByZ[i]);
if (layer->getLayer() != NULL) {
const sp<GraphicBuffer>& buffer(
layer->getLayer()->getActiveBuffer());
if (buffer != NULL) {
format = buffer->getPixelFormat();
if (buffer != NULL) {
format = buffer->getPixelFormat();
}
}
name = layer->getName();
}
int type = l.compositionType;
if (type == HWC_FRAMEBUFFER_TARGET) {
name = "HWC_FRAMEBUFFER_TARGET";
format = disp.format;
}
static char const* compositionTypeName[] = {
"GLES",
"HWC",
"BACKGROUND",
"FB TARGET",
"UNKNOWN"};
if (type >= NELEM(compositionTypeName))
type = NELEM(compositionTypeName) - 1;
result.appendFormat(
" %8s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
l.compositionType ? "OVERLAY" : "FB",
" %10s | %08x | %08x | %08x | %02x | %05x | %08x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d] %s\n",
compositionTypeName[type],
intptr_t(l.handle), l.hints, l.flags, l.transform, l.blending, format,
l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom,
layer->getName().string());
name.string());
}
}
}

View File

@ -36,6 +36,7 @@ extern "C" int clock_nanosleep(clockid_t clock_id, int flags,
struct hwc_composer_device_1;
struct hwc_display_contents_1;
struct hwc_layer_1;
struct hwc_procs;
struct framebuffer_device_t;
@ -43,6 +44,7 @@ namespace android {
// ---------------------------------------------------------------------------
class GraphicBuffer;
class Fence;
class LayerBase;
class Region;
class String8;
@ -97,12 +99,18 @@ public:
// create a work list for numLayers layer. sets HWC_GEOMETRY_CHANGED.
status_t createWorkList(int32_t id, size_t numLayers);
bool supportsFramebufferTarget() const;
// does this display have layers handled by HWC
bool hasHwcComposition(int32_t id) const;
// does this display have layers handled by GLES
bool hasGlesComposition(int32_t id) const;
// get the releaseFence file descriptor for the given display
// the release fence is only valid after commit()
int getAndResetReleaseFenceFd(int32_t id);
// needed forward declarations
class LayerListIterator;
@ -111,7 +119,7 @@ public:
int getVisualID() const;
// Forwarding to FB HAL for pre-HWC-1.1 code (see FramebufferSurface).
int fbPost(buffer_handle_t buffer);
int fbPost(int32_t id, const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
int fbCompositionComplete();
void fbDump(String8& result);
@ -253,7 +261,6 @@ private:
void loadFbHalModule();
LayerListIterator getLayerIterator(int32_t id, size_t index);
size_t getNumLayers(int32_t id) const;
struct cb_context;
@ -269,10 +276,15 @@ private:
void queryDisplayProperties(int disp);
status_t setFramebufferTarget(int32_t id,
const sp<Fence>& acquireFence, const sp<GraphicBuffer>& buf);
struct DisplayData {
DisplayData() : xdpi(0), ydpi(0), refresh(0),
hasFbComp(false), hasOvComp(false),
capacity(0), list(NULL) { }
capacity(0), list(NULL),
framebufferTarget(NULL), fbTargetHandle(NULL) { }
~DisplayData() {
free(list);
}
@ -286,6 +298,8 @@ private:
bool hasOvComp;
size_t capacity;
hwc_display_contents_1* list;
hwc_layer_1* framebufferTarget;
buffer_handle_t fbTargetHandle;
};
sp<SurfaceFlinger> mFlinger;

View File

@ -523,6 +523,10 @@ void Layer::onPostComposition() {
}
}
bool Layer::isVisible() const {
return LayerBaseClient::isVisible() && (mActiveBuffer != NULL);
}
Region Layer::latchBuffer(bool& recomputeVisibleRegions)
{
ATRACE_CALL();

View File

@ -82,6 +82,7 @@ public:
virtual void onRemoved();
virtual sp<Layer> getLayer() const { return const_cast<Layer*>(this); }
virtual void setName(const String8& name);
virtual bool isVisible() const;
// LayerBaseClient interface
virtual wp<IBinder> getSurfaceTextureBinder() const;

View File

@ -321,6 +321,11 @@ bool LayerBase::getFiltering() const
return mFiltering;
}
bool LayerBase::isVisible() const {
const Layer::State& s(mDrawingState);
return !(s.flags & layer_state_t::eLayerHidden) && s.alpha;
}
void LayerBase::draw(const sp<const DisplayDevice>& hw, const Region& clip) const
{
onDraw(hw, clip);

View File

@ -211,6 +211,11 @@ public:
*/
virtual bool isProtected() const { return false; }
/*
* isVisible - true if this layer is visibile, false otherwise
*/
virtual bool isVisible() const;
/** called with the state lock when the surface is removed from the
* current list */
virtual void onRemoved() { }

View File

@ -245,15 +245,6 @@ status_t SurfaceFlinger::selectConfigForPixelFormat(
EGLConfig* const configs = new EGLConfig[numConfigs];
eglChooseConfig(dpy, attrs, configs, numConfigs, &n);
if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
// FIXME: temporary hack until HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED
// is supported by the implementation. we can only be in this case
// if we have HWC 1.1
*outConfig = configs[0];
delete [] configs;
return NO_ERROR;
}
for (int i=0 ; i<n ; i++) {
EGLint nativeVisualId = 0;
eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
@ -273,6 +264,7 @@ EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisua
EGLConfig config;
EGLint dummy;
status_t err;
EGLint attribs[] = {
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RED_SIZE, 8,
@ -390,6 +382,9 @@ status_t SurfaceFlinger::readyToRun()
mEGLConfig = selectEGLConfig(mEGLDisplay, format);
mEGLContext = createGLContext(mEGLDisplay, mEGLConfig);
LOG_ALWAYS_FATAL_IF(mEGLContext == EGL_NO_CONTEXT,
"couldn't create EGLContext");
// initialize our non-virtual displays
for (size_t i=0 ; i<DisplayDevice::NUM_DISPLAY_TYPES ; i++) {
mDefaultDisplays[i] = new BBinder();
@ -725,10 +720,7 @@ void SurfaceFlinger::doDebugFlashRegions()
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
hw->compositionComplete();
// FIXME
if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
}
hw->swapBuffers(getHwComposer());
}
}
}
@ -885,6 +877,7 @@ void SurfaceFlinger::postFramebuffer()
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> hw(mDisplays[dpy]);
const Vector< sp<LayerBase> >& currentLayers(hw->getVisibleLayersSortedByZ());
hw->onSwapBuffersCompleted(hwc);
const size_t count = currentLayers.size();
int32_t id = hw->getHwcDisplayId();
if (id >=0 && hwc.initCheck() == NO_ERROR) {
@ -1160,7 +1153,7 @@ void SurfaceFlinger::computeVisibleRegions(
// handle hidden surfaces by setting the visible region to empty
if (CC_LIKELY(!(s.flags & layer_state_t::eLayerHidden) && s.alpha)) {
if (CC_LIKELY(layer->isVisible())) {
const bool translucent = !layer->isOpaque();
Rect bounds(layer->computeBounds());
visibleRegion.set(bounds);
@ -1308,20 +1301,11 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
doComposeSurfaces(hw, dirtyRegion);
// FIXME: we need to call eglSwapBuffers() on displays that have
// GL composition and only on those.
// however, currently hwc.commit() already does that for the main
// display (if there is a hwc) and never for the other ones
if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL ||
getHwComposer().initCheck() != NO_ERROR) {
// FIXME: EGL spec says:
// "surface must be bound to the calling thread's current context,
// for the current rendering API."
eglSwapBuffers(mEGLDisplay, hw->getEGLSurface());
}
// update the swap region and clear the dirty region
hw->swapRegion.orSelf(dirtyRegion);
// swap buffers (presentation)
hw->swapBuffers(getHwComposer());
}
void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const Region& dirty)
@ -1388,6 +1372,12 @@ void SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& hw, const
layer->draw(hw, clip);
break;
}
case HWC_FRAMEBUFFER_TARGET: {
// this should not happen as the iterator shouldn't
// let us get there.
ALOGW("HWC_FRAMEBUFFER_TARGET found in hwc list (index=%d)", i);
break;
}
}
}
layer->setAcquireFence(hw, *cur);