FramebufferSurface.cpp revision b42b1ac1587aebda5e2f334d95b620271fafba4e
1/* 2 ** 3 ** Copyright 2007 The Android Open Source Project 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 */ 17 18#include <stdlib.h> 19#include <stdio.h> 20#include <string.h> 21#include <errno.h> 22 23#include <cutils/log.h> 24 25#include <utils/String8.h> 26 27#include <ui/Rect.h> 28 29#include <EGL/egl.h> 30 31#include <hardware/hardware.h> 32#include <gui/SurfaceTextureClient.h> 33#include <ui/GraphicBuffer.h> 34 35#include "DisplayHardware/FramebufferSurface.h" 36 37// ---------------------------------------------------------------------------- 38namespace android { 39// ---------------------------------------------------------------------------- 40 41 42/* 43 * This implements the (main) framebuffer management. This class is used 44 * mostly by SurfaceFlinger, but also by command line GL application. 45 * 46 */ 47 48FramebufferSurface::FramebufferSurface() 49 : SurfaceTextureClient(), 50 fbDev(0), mCurrentBufferIndex(-1), mUpdateOnDemand(false) 51{ 52 hw_module_t const* module; 53 if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) { 54 int stride; 55 int err; 56 int i; 57 err = framebuffer_open(module, &fbDev); 58 ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err)); 59 60 // bail out if we can't initialize the modules 61 if (!fbDev) 62 return; 63 64 mUpdateOnDemand = (fbDev->setUpdateRect != 0); 65 66 const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; 67 const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi; 68 const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi; 69 const_cast<int&>(ANativeWindow::minSwapInterval) = fbDev->minSwapInterval; 70 const_cast<int&>(ANativeWindow::maxSwapInterval) = fbDev->maxSwapInterval; 71 } else { 72 ALOGE("Couldn't get gralloc module"); 73 } 74 75 class GraphicBufferAlloc : public BnGraphicBufferAlloc { 76 public: 77 GraphicBufferAlloc() { }; 78 virtual ~GraphicBufferAlloc() { }; 79 virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h, 80 PixelFormat format, uint32_t usage, status_t* error) { 81 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); 82 return graphicBuffer; 83 } 84 }; 85 86 mBufferQueue = new BufferQueue(true, NUM_FRAME_BUFFERS, new GraphicBufferAlloc()); 87 mBufferQueue->setConsumerUsageBits(GRALLOC_USAGE_HW_FB|GRALLOC_USAGE_HW_RENDER|GRALLOC_USAGE_HW_COMPOSER); 88 mBufferQueue->setDefaultBufferFormat(fbDev->format); 89 mBufferQueue->setDefaultBufferSize(fbDev->width, fbDev->height); 90 mBufferQueue->setSynchronousMode(true); 91 mBufferQueue->setBufferCountServer(NUM_FRAME_BUFFERS); 92 setISurfaceTexture(mBufferQueue); 93} 94 95void FramebufferSurface::onFirstRef() { 96 class Listener : public BufferQueue::ConsumerListener { 97 const wp<FramebufferSurface> that; 98 virtual ~Listener() { } 99 virtual void onBuffersReleased() { } 100 void onFrameAvailable() { 101 sp<FramebufferSurface> self = that.promote(); 102 if (self != NULL) { 103 BufferQueue::BufferItem item; 104 status_t err = self->mBufferQueue->acquireBuffer(&item); 105 if (err == 0) { 106 if (item.mGraphicBuffer != 0) { 107 self->mBuffers[item.mBuf] = item.mGraphicBuffer; 108 } 109 if (item.mFence.get()) { 110 err = item.mFence->wait(Fence::TIMEOUT_NEVER); 111 if (err) { 112 ALOGE("failed waiting for buffer's fence: %d", err); 113 self->mBufferQueue->releaseBuffer(item.mBuf, 114 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, 115 item.mFence); 116 return; 117 } 118 } 119 self->fbDev->post(self->fbDev, self->mBuffers[item.mBuf]->handle); 120 if (self->mCurrentBufferIndex >= 0) { 121 self->mBufferQueue->releaseBuffer(self->mCurrentBufferIndex, 122 EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, Fence::NO_FENCE); 123 } 124 self->mCurrentBufferIndex = item.mBuf; 125 } 126 } 127 } 128 public: 129 Listener(const sp<FramebufferSurface>& that) : that(that) { } 130 }; 131 132 mBufferQueue->setConsumerName(String8("FramebufferSurface")); 133 mBufferQueue->consumerConnect(new Listener(this)); 134} 135 136FramebufferSurface::~FramebufferSurface() { 137 if (fbDev) { 138 framebuffer_close(fbDev); 139 } 140} 141 142status_t FramebufferSurface::setUpdateRectangle(const Rect& r) 143{ 144 if (!mUpdateOnDemand) { 145 return INVALID_OPERATION; 146 } 147 return fbDev->setUpdateRect(fbDev, r.left, r.top, r.width(), r.height()); 148} 149 150status_t FramebufferSurface::compositionComplete() 151{ 152 if (fbDev->compositionComplete) { 153 return fbDev->compositionComplete(fbDev); 154 } 155 return INVALID_OPERATION; 156} 157 158void FramebufferSurface::dump(String8& result) { 159 if (fbDev->common.version >= 1 && fbDev->dump) { 160 const size_t SIZE = 4096; 161 char buffer[SIZE]; 162 163 fbDev->dump(fbDev, buffer, SIZE); 164 result.append(buffer); 165 } 166} 167 168int FramebufferSurface::query(int what, int* value) const { 169 Mutex::Autolock _l(mLock); 170 framebuffer_device_t* fb = fbDev; 171 switch (what) { 172 case NATIVE_WINDOW_DEFAULT_WIDTH: 173 case NATIVE_WINDOW_WIDTH: 174 *value = fb->width; 175 return NO_ERROR; 176 case NATIVE_WINDOW_DEFAULT_HEIGHT: 177 case NATIVE_WINDOW_HEIGHT: 178 *value = fb->height; 179 return NO_ERROR; 180 case NATIVE_WINDOW_FORMAT: 181 *value = fb->format; 182 return NO_ERROR; 183 case NATIVE_WINDOW_CONCRETE_TYPE: 184 *value = NATIVE_WINDOW_FRAMEBUFFER; 185 return NO_ERROR; 186 case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER: 187 *value = 0; 188 return NO_ERROR; 189 case NATIVE_WINDOW_TRANSFORM_HINT: 190 *value = 0; 191 return NO_ERROR; 192 } 193 return SurfaceTextureClient::query(what, value); 194} 195 196// ---------------------------------------------------------------------------- 197}; // namespace android 198// ---------------------------------------------------------------------------- 199