Merge "Fix a couple issues with the new hwcomposer HAL" into gingerbread
This commit is contained in:
committed by
Android (Google) Code Review
commit
b7d1be01ae
@@ -34,7 +34,7 @@ namespace android {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
HWComposer::HWComposer()
|
HWComposer::HWComposer()
|
||||||
: mModule(0), mHwc(0), mList(0),
|
: mModule(0), mHwc(0), mList(0), mCapacity(0),
|
||||||
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
|
mDpy(EGL_NO_DISPLAY), mSur(EGL_NO_SURFACE)
|
||||||
{
|
{
|
||||||
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
|
int err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule);
|
||||||
@@ -63,10 +63,13 @@ void HWComposer::setFrameBuffer(EGLDisplay dpy, EGLSurface sur) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t HWComposer::createWorkList(size_t numLayers) {
|
status_t HWComposer::createWorkList(size_t numLayers) {
|
||||||
if (mHwc && (!mList || mList->numHwLayers < numLayers)) {
|
if (mHwc) {
|
||||||
free(mList);
|
if (!mList || mCapacity < numLayers) {
|
||||||
size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
|
free(mList);
|
||||||
mList = (hwc_layer_list_t*)malloc(size);
|
size_t size = sizeof(hwc_layer_list) + numLayers*sizeof(hwc_layer_t);
|
||||||
|
mList = (hwc_layer_list_t*)malloc(size);
|
||||||
|
mCapacity = numLayers;
|
||||||
|
}
|
||||||
mList->flags = HWC_GEOMETRY_CHANGED;
|
mList->flags = HWC_GEOMETRY_CHANGED;
|
||||||
mList->numHwLayers = numLayers;
|
mList->numHwLayers = numLayers;
|
||||||
}
|
}
|
||||||
@@ -84,12 +87,12 @@ status_t HWComposer::commit() const {
|
|||||||
return (status_t)err;
|
return (status_t)err;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWComposer::iterator HWComposer::begin() {
|
size_t HWComposer::getNumLayers() const {
|
||||||
return mList ? &(mList->hwLayers[0]) : NULL;
|
return mList ? mList->numHwLayers : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
HWComposer::iterator HWComposer::end() {
|
hwc_layer_t* HWComposer::getLayers() const {
|
||||||
return mList ? &(mList->hwLayers[mList->numHwLayers]) : NULL;
|
return mList ? mList->hwLayers : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -49,16 +49,14 @@ public:
|
|||||||
status_t commit() const;
|
status_t commit() const;
|
||||||
|
|
||||||
|
|
||||||
typedef hwc_layer_t const * const_iterator;
|
size_t getNumLayers() const;
|
||||||
typedef hwc_layer_t* iterator;
|
hwc_layer_t* getLayers() const;
|
||||||
|
|
||||||
iterator begin();
|
|
||||||
iterator end();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
hw_module_t const* mModule;
|
hw_module_t const* mModule;
|
||||||
hwc_composer_device_t* mHwc;
|
hwc_composer_device_t* mHwc;
|
||||||
hwc_layer_list_t* mList;
|
hwc_layer_list_t* mList;
|
||||||
|
size_t mCapacity;
|
||||||
hwc_display_t mDpy;
|
hwc_display_t mDpy;
|
||||||
hwc_surface_t mSur;
|
hwc_surface_t mSur;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -755,10 +755,9 @@ void SurfaceFlinger::handleWorkList()
|
|||||||
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
|
const Vector< sp<LayerBase> >& currentLayers(mVisibleLayersSortedByZ);
|
||||||
const size_t count = currentLayers.size();
|
const size_t count = currentLayers.size();
|
||||||
hwc.createWorkList(count);
|
hwc.createWorkList(count);
|
||||||
HWComposer::iterator cur(hwc.begin());
|
hwc_layer_t* const cur(hwc.getLayers());
|
||||||
HWComposer::iterator last(hwc.end());
|
for (size_t i=0 ; cur && i<count ; i++) {
|
||||||
for (size_t i=0 ; (i<count) && (cur!=last) ; ++i, ++cur) {
|
currentLayers[i]->setGeometry(&cur[i]);
|
||||||
currentLayers[i]->setGeometry(cur);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -829,47 +828,41 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
|
|||||||
|
|
||||||
status_t err = NO_ERROR;
|
status_t err = NO_ERROR;
|
||||||
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
|
||||||
const size_t count = layers.size();
|
size_t count = layers.size();
|
||||||
|
|
||||||
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
const DisplayHardware& hw(graphicPlane(0).displayHardware());
|
||||||
HWComposer& hwc(hw.getHwComposer());
|
HWComposer& hwc(hw.getHwComposer());
|
||||||
HWComposer::iterator cur(hwc.begin());
|
hwc_layer_t* const cur(hwc.getLayers());
|
||||||
HWComposer::iterator last(hwc.end());
|
|
||||||
|
|
||||||
// update the per-frame h/w composer data for each layer
|
LOGE_IF(cur && hwc.getNumLayers() != count,
|
||||||
if (cur != last) {
|
"HAL number of layers (%d) doesn't match surfaceflinger (%d)",
|
||||||
for (size_t i=0 ; i<count && cur!=last ; ++i, ++cur) {
|
hwc.getNumLayers(), count);
|
||||||
layers[i]->setPerFrameData(cur);
|
|
||||||
|
// just to be extra-safe, use the smallest count
|
||||||
|
count = count < hwc.getNumLayers() ? count : hwc.getNumLayers();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* update the per-frame h/w composer data for each layer
|
||||||
|
* and build the transparent region of the FB
|
||||||
|
*/
|
||||||
|
Region transparent;
|
||||||
|
if (cur) {
|
||||||
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
|
layer->setPerFrameData(&cur[i]);
|
||||||
|
if (cur[i].hints & HWC_HINT_CLEAR_FB) {
|
||||||
|
if (!(layer->needsBlending())) {
|
||||||
|
transparent.orSelf(layer->visibleRegionScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
err = hwc.prepare();
|
err = hwc.prepare();
|
||||||
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
|
||||||
}
|
}
|
||||||
|
|
||||||
// and then, render the layers targeted at the framebuffer
|
/*
|
||||||
Region transparent(hw.bounds());
|
* clear the area of the FB that need to be transparent
|
||||||
for (size_t i=0 ; i<count ; ++i) {
|
*/
|
||||||
|
|
||||||
// see if we need to skip this layer
|
|
||||||
if (!err && cur != last) {
|
|
||||||
if (!((cur->compositionType == HWC_FRAMEBUFFER) ||
|
|
||||||
(cur->flags & HWC_SKIP_LAYER))) {
|
|
||||||
++cur;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the layer into the framebuffer
|
|
||||||
const sp<LayerBase>& layer(layers[i]);
|
|
||||||
transparent.subtractSelf(layer->visibleRegionScreen);
|
|
||||||
const Region clip(dirty.intersect(layer->visibleRegionScreen));
|
|
||||||
if (!clip.isEmpty()) {
|
|
||||||
layer->draw(clip);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// finally clear everything we didn't draw as a result of calling
|
|
||||||
// prepare (this leaves the FB transparent).
|
|
||||||
transparent.andSelf(dirty);
|
transparent.andSelf(dirty);
|
||||||
if (!transparent.isEmpty()) {
|
if (!transparent.isEmpty()) {
|
||||||
glClearColor(0,0,0,0);
|
glClearColor(0,0,0,0);
|
||||||
@@ -883,6 +876,25 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* and then, render the layers targeted at the framebuffer
|
||||||
|
*/
|
||||||
|
for (size_t i=0 ; i<count ; i++) {
|
||||||
|
if (cur) {
|
||||||
|
if (!(cur[i].compositionType == HWC_FRAMEBUFFER) ||
|
||||||
|
cur[i].flags & HWC_SKIP_LAYER) {
|
||||||
|
// skip layers handled by the HAL
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const sp<LayerBase>& layer(layers[i]);
|
||||||
|
const Region clip(dirty.intersect(layer->visibleRegionScreen));
|
||||||
|
if (!clip.isEmpty()) {
|
||||||
|
layer->draw(clip);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SurfaceFlinger::unlockClients()
|
void SurfaceFlinger::unlockClients()
|
||||||
|
|||||||
Reference in New Issue
Block a user