Implement SurfaceFlinger's ANW on top of BufferQueue
SF now has its own implementation of ANW for the framebuffer and it uses BufferQueue. FramebufferNativeWindow is now only used by stand-alone apps. Change-Id: Iddeb24087df62bd92b0f78e391dda9b97ddc859c
This commit is contained in:
parent
04d7eaf138
commit
3e87601170
@ -96,7 +96,9 @@ public:
|
||||
// allowSynchronousMode specifies whether or not synchronous mode can be
|
||||
// enabled.
|
||||
// bufferCount sets the minimum number of undequeued buffers for this queue
|
||||
BufferQueue( bool allowSynchronousMode = true, int bufferCount = MIN_UNDEQUEUED_BUFFERS);
|
||||
BufferQueue(bool allowSynchronousMode = true,
|
||||
int bufferCount = MIN_UNDEQUEUED_BUFFERS,
|
||||
const sp<IGraphicBufferAlloc>& allocator = NULL);
|
||||
virtual ~BufferQueue();
|
||||
|
||||
virtual int query(int what, int* value);
|
||||
|
@ -81,7 +81,8 @@ static const char* scalingModeName(int scalingMode) {
|
||||
}
|
||||
}
|
||||
|
||||
BufferQueue::BufferQueue( bool allowSynchronousMode, int bufferCount ) :
|
||||
BufferQueue::BufferQueue(bool allowSynchronousMode, int bufferCount,
|
||||
const sp<IGraphicBufferAlloc>& allocator) :
|
||||
mDefaultWidth(1),
|
||||
mDefaultHeight(1),
|
||||
mPixelFormat(PIXEL_FORMAT_RGBA_8888),
|
||||
@ -105,10 +106,14 @@ BufferQueue::BufferQueue( bool allowSynchronousMode, int bufferCount ) :
|
||||
mConsumerName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
|
||||
|
||||
ST_LOGV("BufferQueue");
|
||||
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
|
||||
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
|
||||
if (mGraphicBufferAlloc == 0) {
|
||||
ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
|
||||
if (allocator == NULL) {
|
||||
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
|
||||
mGraphicBufferAlloc = composer->createGraphicBufferAlloc();
|
||||
if (mGraphicBufferAlloc == 0) {
|
||||
ST_LOGE("createGraphicBufferAlloc() failed in BufferQueue()");
|
||||
}
|
||||
} else {
|
||||
mGraphicBufferAlloc = allocator;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ LOCAL_SRC_FILES:= \
|
||||
LayerScreenshot.cpp \
|
||||
DisplayHardware/DisplayHardware.cpp \
|
||||
DisplayHardware/DisplayHardwareBase.cpp \
|
||||
DisplayHardware/FramebufferSurface.cpp \
|
||||
DisplayHardware/HWComposer.cpp \
|
||||
DisplayHardware/PowerHAL.cpp \
|
||||
GLExtensions.cpp \
|
||||
|
@ -25,13 +25,13 @@
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <ui/FramebufferNativeWindow.h>
|
||||
|
||||
#include <GLES/gl.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
|
||||
#include "DisplayHardware/DisplayHardware.h"
|
||||
#include "DisplayHardware/FramebufferSurface.h"
|
||||
|
||||
#include <hardware/gralloc.h>
|
||||
|
||||
@ -148,7 +148,7 @@ static status_t selectConfigForPixelFormat(
|
||||
|
||||
void DisplayHardware::init(uint32_t dpy)
|
||||
{
|
||||
mNativeWindow = new FramebufferNativeWindow();
|
||||
mNativeWindow = new FramebufferSurface();
|
||||
framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
|
||||
if (!fbDev) {
|
||||
ALOGE("Display subsystem failed to initialize. check logs. exiting...");
|
||||
|
@ -35,7 +35,7 @@
|
||||
|
||||
namespace android {
|
||||
|
||||
class FramebufferNativeWindow;
|
||||
class FramebufferSurface;
|
||||
|
||||
class DisplayHardware :
|
||||
public DisplayHardwareBase,
|
||||
@ -144,7 +144,7 @@ private:
|
||||
// protected by mLock
|
||||
wp<VSyncHandler> mVSyncHandler;
|
||||
|
||||
sp<FramebufferNativeWindow> mNativeWindow;
|
||||
sp<FramebufferSurface> mNativeWindow;
|
||||
};
|
||||
|
||||
}; // namespace android
|
||||
|
188
services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
Normal file
188
services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
**
|
||||
** Copyright 2007 The Android Open Source Project
|
||||
**
|
||||
** 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <cutils/log.h>
|
||||
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include <ui/Rect.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <gui/SurfaceTextureClient.h>
|
||||
#include <ui/GraphicBuffer.h>
|
||||
|
||||
#include "DisplayHardware/FramebufferSurface.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
* This implements the (main) framebuffer management. This class is used
|
||||
* mostly by SurfaceFlinger, but also by command line GL application.
|
||||
*
|
||||
*/
|
||||
|
||||
FramebufferSurface::FramebufferSurface()
|
||||
: SurfaceTextureClient(),
|
||||
fbDev(0), mCurrentBufferIndex(-1), mUpdateOnDemand(false)
|
||||
{
|
||||
hw_module_t const* module;
|
||||
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
|
||||
int stride;
|
||||
int err;
|
||||
int i;
|
||||
err = framebuffer_open(module, &fbDev);
|
||||
ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
|
||||
|
||||
// bail out if we can't initialize the modules
|
||||
if (!fbDev)
|
||||
return;
|
||||
|
||||
mUpdateOnDemand = (fbDev->setUpdateRect != 0);
|
||||
|
||||
const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
|
||||
const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
|
||||
const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
|
||||
const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval;
|
||||
const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval;
|
||||
} else {
|
||||
ALOGE("Couldn't get gralloc module");
|
||||
}
|
||||
|
||||
class GraphicBufferAlloc : public BnGraphicBufferAlloc {
|
||||
public:
|
||||
GraphicBufferAlloc() { };
|
||||
virtual ~GraphicBufferAlloc() { };
|
||||
virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
|
||||
PixelFormat format, uint32_t usage, status_t* error) {
|
||||
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
|
||||
return graphicBuffer;
|
||||
}
|
||||
};
|
||||
|
||||
mBufferQueue = new BufferQueue(true, NUM_FRAME_BUFFERS, new GraphicBufferAlloc());
|
||||
mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB|GRALLOC_USAGE_HW_RENDER|GRALLOC_USAGE_HW_COMPOSER);
|
||||
mBufferQueue->setDefaultBufferFormat(fbDev->format);
|
||||
mBufferQueue->setDefaultBufferSize(fbDev->width, fbDev->height);
|
||||
mBufferQueue->setSynchronousMode(true);
|
||||
mBufferQueue->setBufferCountServer(NUM_FRAME_BUFFERS);
|
||||
setISurfaceTexture(mBufferQueue);
|
||||
}
|
||||
|
||||
void FramebufferSurface::onFirstRef() {
|
||||
class Listener : public BufferQueue::ConsumerListener {
|
||||
const wp<FramebufferSurface> that;
|
||||
virtual ~Listener() { }
|
||||
virtual void onBuffersReleased() { }
|
||||
void onFrameAvailable() {
|
||||
sp<FramebufferSurface> self = that.promote();
|
||||
if (self != NULL) {
|
||||
BufferQueue::BufferItem item;
|
||||
status_t err = self->mBufferQueue->acquireBuffer(&item);
|
||||
if (err == 0) {
|
||||
if (item.mGraphicBuffer != 0) {
|
||||
self->mBuffers[item.mBuf] = item.mGraphicBuffer;
|
||||
}
|
||||
self->fbDev->post(self->fbDev, self->mBuffers[item.mBuf]->handle);
|
||||
if (self->mCurrentBufferIndex >= 0) {
|
||||
self->mBufferQueue->releaseBuffer(self->mCurrentBufferIndex,
|
||||
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
|
||||
}
|
||||
self->mCurrentBufferIndex = item.mBuf;
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
Listener(const sp<FramebufferSurface>& that) : that(that) { }
|
||||
};
|
||||
|
||||
mBufferQueue->setConsumerName(String8("FramebufferSurface"));
|
||||
mBufferQueue->consumerConnect(new Listener(this));
|
||||
}
|
||||
|
||||
FramebufferSurface::~FramebufferSurface() {
|
||||
if (fbDev) {
|
||||
framebuffer_close(fbDev);
|
||||
}
|
||||
}
|
||||
|
||||
status_t FramebufferSurface::setUpdateRectangle(const Rect& r)
|
||||
{
|
||||
if (!mUpdateOnDemand) {
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height());
|
||||
}
|
||||
|
||||
status_t FramebufferSurface::compositionComplete()
|
||||
{
|
||||
if (fbDev->compositionComplete) {
|
||||
return fbDev->compositionComplete(fbDev);
|
||||
}
|
||||
return INVALID_OPERATION;
|
||||
}
|
||||
|
||||
void FramebufferSurface::dump(String8& result) {
|
||||
if (fbDev->common.version >= 1 && fbDev->dump) {
|
||||
const size_t SIZE = 4096;
|
||||
char buffer[SIZE];
|
||||
|
||||
fbDev->dump(fbDev, buffer, SIZE);
|
||||
result.append(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int FramebufferSurface::query(int what, int* value) const {
|
||||
Mutex::Autolock _l(mLock);
|
||||
framebuffer_device_t* fb = fbDev;
|
||||
switch (what) {
|
||||
case NATIVE_WINDOW_DEFAULT_WIDTH:
|
||||
case NATIVE_WINDOW_WIDTH:
|
||||
*value = fb->width;
|
||||
return NO_ERROR;
|
||||
case NATIVE_WINDOW_DEFAULT_HEIGHT:
|
||||
case NATIVE_WINDOW_HEIGHT:
|
||||
*value = fb->height;
|
||||
return NO_ERROR;
|
||||
case NATIVE_WINDOW_FORMAT:
|
||||
*value = fb->format;
|
||||
return NO_ERROR;
|
||||
case NATIVE_WINDOW_CONCRETE_TYPE:
|
||||
*value = NATIVE_WINDOW_FRAMEBUFFER;
|
||||
return NO_ERROR;
|
||||
case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
|
||||
*value = 0;
|
||||
return NO_ERROR;
|
||||
case NATIVE_WINDOW_TRANSFORM_HINT:
|
||||
*value = 0;
|
||||
return NO_ERROR;
|
||||
}
|
||||
return SurfaceTextureClient::query(what, value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ----------------------------------------------------------------------------
|
71
services/surfaceflinger/DisplayHardware/FramebufferSurface.h
Normal file
71
services/surfaceflinger/DisplayHardware/FramebufferSurface.h
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2007 The Android Open Source Project
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef ANDROID_SF_FRAMEBUFFER_SURFACE_H
|
||||
#define ANDROID_SF_FRAMEBUFFER_SURFACE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <gui/SurfaceTextureClient.h>
|
||||
|
||||
#define NUM_FRAME_BUFFERS 2
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
namespace android {
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class Rect;
|
||||
class String8;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
class FramebufferSurface : public SurfaceTextureClient {
|
||||
public:
|
||||
FramebufferSurface();
|
||||
|
||||
virtual void onFirstRef();
|
||||
|
||||
framebuffer_device_t const * getDevice() const { return fbDev; }
|
||||
|
||||
bool isUpdateOnDemand() const { return mUpdateOnDemand; }
|
||||
status_t setUpdateRectangle(const Rect& updateRect);
|
||||
status_t compositionComplete();
|
||||
|
||||
void dump(String8& result);
|
||||
|
||||
private:
|
||||
virtual ~FramebufferSurface(); // this class cannot be overloaded
|
||||
virtual int query(int what, int* value) const;
|
||||
|
||||
framebuffer_device_t* fbDev;
|
||||
|
||||
sp<BufferQueue> mBufferQueue;
|
||||
int mCurrentBufferIndex;
|
||||
sp<GraphicBuffer> mBuffers[NUM_FRAME_BUFFERS];
|
||||
|
||||
mutable Mutex mLock;
|
||||
bool mUpdateOnDemand;
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
}; // namespace android
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#endif // ANDROID_SF_FRAMEBUFFER_SURFACE_H
|
||||
|
Loading…
Reference in New Issue
Block a user