diff options
Diffstat (limited to 'widget/gonk/libdisplay')
-rw-r--r-- | widget/gonk/libdisplay/BootAnimation.cpp | 726 | ||||
-rw-r--r-- | widget/gonk/libdisplay/BootAnimation.h | 30 | ||||
-rw-r--r-- | widget/gonk/libdisplay/DisplaySurface.h | 112 | ||||
-rw-r--r-- | widget/gonk/libdisplay/FramebufferSurface.cpp | 207 | ||||
-rw-r--r-- | widget/gonk/libdisplay/FramebufferSurface.h | 93 | ||||
-rw-r--r-- | widget/gonk/libdisplay/GonkDisplay.h | 91 | ||||
-rw-r--r-- | widget/gonk/libdisplay/GonkDisplayJB.cpp | 461 | ||||
-rw-r--r-- | widget/gonk/libdisplay/GonkDisplayJB.h | 85 | ||||
-rw-r--r-- | widget/gonk/libdisplay/GraphicBufferAlloc.cpp | 53 | ||||
-rw-r--r-- | widget/gonk/libdisplay/GraphicBufferAlloc.h | 44 | ||||
-rw-r--r-- | widget/gonk/libdisplay/VirtualDisplaySurface.cpp | 635 | ||||
-rw-r--r-- | widget/gonk/libdisplay/VirtualDisplaySurface.h | 250 | ||||
-rw-r--r-- | widget/gonk/libdisplay/moz.build | 59 |
13 files changed, 0 insertions, 2846 deletions
diff --git a/widget/gonk/libdisplay/BootAnimation.cpp b/widget/gonk/libdisplay/BootAnimation.cpp deleted file mode 100644 index c275179fc..000000000 --- a/widget/gonk/libdisplay/BootAnimation.cpp +++ /dev/null @@ -1,726 +0,0 @@ -/* Copyright 2012 Mozilla Foundation and Mozilla contributors - * - * 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 <algorithm> -#include <endian.h> -#include <fcntl.h> -#include <pthread.h> -#include <string> -#include <sys/mman.h> -#include <sys/stat.h> -#include <vector> -#include "mozilla/FileUtils.h" -#include "png.h" - -#include "android/log.h" -#include "GonkDisplay.h" -#include "hardware/gralloc.h" - -#define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "Gonk" , ## args) -#define LOGW(args...) __android_log_print(ANDROID_LOG_WARN, "Gonk", ## args) -#define LOGE(args...) __android_log_print(ANDROID_LOG_ERROR, "Gonk", ## args) - -using namespace mozilla; -using namespace std; - -static pthread_t sAnimationThread; -static bool sRunAnimation; - -/* See http://www.pkware.com/documents/casestudies/APPNOTE.TXT */ -struct local_file_header { - uint32_t signature; - uint16_t min_version; - uint16_t general_flag; - uint16_t compression; - uint16_t lastmod_time; - uint16_t lastmod_date; - uint32_t crc32; - uint32_t compressed_size; - uint32_t uncompressed_size; - uint16_t filename_size; - uint16_t extra_field_size; - char data[0]; - - uint32_t GetDataSize() const - { - return letoh32(uncompressed_size); - } - - uint32_t GetSize() const - { - /* XXX account for data descriptor */ - return sizeof(local_file_header) + letoh16(filename_size) + - letoh16(extra_field_size) + GetDataSize(); - } - - const char * GetData() const - { - return data + letoh16(filename_size) + letoh16(extra_field_size); - } -} __attribute__((__packed__)); - -struct data_descriptor { - uint32_t crc32; - uint32_t compressed_size; - uint32_t uncompressed_size; -} __attribute__((__packed__)); - -struct cdir_entry { - uint32_t signature; - uint16_t creator_version; - uint16_t min_version; - uint16_t general_flag; - uint16_t compression; - uint16_t lastmod_time; - uint16_t lastmod_date; - uint32_t crc32; - uint32_t compressed_size; - uint32_t uncompressed_size; - uint16_t filename_size; - uint16_t extra_field_size; - uint16_t file_comment_size; - uint16_t disk_num; - uint16_t internal_attr; - uint32_t external_attr; - uint32_t offset; - char data[0]; - - uint32_t GetDataSize() const - { - return letoh32(compressed_size); - } - - uint32_t GetSize() const - { - return sizeof(cdir_entry) + letoh16(filename_size) + - letoh16(extra_field_size) + letoh16(file_comment_size); - } - - bool Valid() const - { - return signature == htole32(0x02014b50); - } -} __attribute__((__packed__)); - -struct cdir_end { - uint32_t signature; - uint16_t disk_num; - uint16_t cdir_disk; - uint16_t disk_entries; - uint16_t cdir_entries; - uint32_t cdir_size; - uint32_t cdir_offset; - uint16_t comment_size; - char comment[0]; - - bool Valid() const - { - return signature == htole32(0x06054b50); - } -} __attribute__((__packed__)); - -/* We don't have access to libjar and the zip reader in android - * doesn't quite fit what we want to do. */ -class ZipReader { - const char *mBuf; - const cdir_end *mEnd; - const char *mCdir_limit; - uint32_t mBuflen; - -public: - ZipReader() : mBuf(nullptr) {} - ~ZipReader() { - if (mBuf) - munmap((void *)mBuf, mBuflen); - } - - bool OpenArchive(const char *path) - { - int fd; - do { - fd = open(path, O_RDONLY); - } while (fd == -1 && errno == EINTR); - if (fd == -1) - return false; - - struct stat sb; - if (fstat(fd, &sb) == -1 || sb.st_size < sizeof(cdir_end)) { - close(fd); - return false; - } - - mBuflen = sb.st_size; - mBuf = (char *)mmap(nullptr, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); - close(fd); - - if (!mBuf) { - return false; - } - - madvise(mBuf, sb.st_size, MADV_SEQUENTIAL); - - mEnd = (cdir_end *)(mBuf + mBuflen - sizeof(cdir_end)); - while (!mEnd->Valid() && - (char *)mEnd > mBuf) { - mEnd = (cdir_end *)((char *)mEnd - 1); - } - - mCdir_limit = mBuf + letoh32(mEnd->cdir_offset) + letoh32(mEnd->cdir_size); - - if (!mEnd->Valid() || mCdir_limit > (char *)mEnd) { - munmap((void *)mBuf, mBuflen); - mBuf = nullptr; - return false; - } - - return true; - } - - /* Pass null to get the first cdir entry */ - const cdir_entry * GetNextEntry(const cdir_entry *prev) - { - const cdir_entry *entry; - if (prev) - entry = (cdir_entry *)((char *)prev + prev->GetSize()); - else - entry = (cdir_entry *)(mBuf + letoh32(mEnd->cdir_offset)); - - if (((char *)entry + entry->GetSize()) > mCdir_limit || - !entry->Valid()) - return nullptr; - return entry; - } - - string GetEntryName(const cdir_entry *entry) - { - uint16_t len = letoh16(entry->filename_size); - - string name; - name.append(entry->data, len); - return name; - } - - const local_file_header * GetLocalEntry(const cdir_entry *entry) - { - const local_file_header * data = - (local_file_header *)(mBuf + letoh32(entry->offset)); - if (((char *)data + data->GetSize()) > (char *)mEnd) - return nullptr; - return data; - } -}; - -struct AnimationFrame { - char path[256]; - png_color_16 bgcolor; - char *buf; - const local_file_header *file; - uint32_t width; - uint32_t height; - uint16_t bytepp; - bool has_bgcolor; - - AnimationFrame() : buf(nullptr) {} - AnimationFrame(const AnimationFrame &frame) : buf(nullptr) { - strncpy(path, frame.path, sizeof(path)); - file = frame.file; - } - ~AnimationFrame() - { - if (buf) - free(buf); - } - - bool operator<(const AnimationFrame &other) const - { - return strcmp(path, other.path) < 0; - } - - void ReadPngFrame(int outputFormat); -}; - -struct AnimationPart { - int32_t count; - int32_t pause; - // If you alter the size of the path, change ReadFromString() as well. - char path[256]; - vector<AnimationFrame> frames; - - bool - ReadFromString(const char* aLine) - { - MOZ_ASSERT(aLine); - // this 255 value must be in sync with AnimationPart::path. - return sscanf(aLine, "p %d %d %255s", &count, &pause, path) == 3; - } -}; - -struct RawReadState { - const char *start; - uint32_t offset; - uint32_t length; -}; - -static void -RawReader(png_structp png_ptr, png_bytep data, png_size_t length) -{ - RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr); - if (length > (state->length - state->offset)) - png_error(png_ptr, "PNG read overrun"); - - memcpy(data, state->start + state->offset, length); - state->offset += length; -} - -static void -TransformTo565(png_structp png_ptr, png_row_infop row_info, png_bytep data) -{ - uint16_t *outbuf = (uint16_t *)data; - uint8_t *inbuf = (uint8_t *)data; - for (uint32_t i = 0; i < row_info->rowbytes; i += 3) { - *outbuf++ = ((inbuf[i] & 0xF8) << 8) | - ((inbuf[i + 1] & 0xFC) << 3) | - ((inbuf[i + 2] ) >> 3); - } -} - -static uint16_t -GetFormatBPP(int aFormat) -{ - uint16_t bpp = 0; - - switch (aFormat) { - case HAL_PIXEL_FORMAT_BGRA_8888: - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - bpp = 4; - break; - case HAL_PIXEL_FORMAT_RGB_888: - bpp = 3; - break; - default: - LOGW("Unknown pixel format %d. Assuming RGB 565.", aFormat); - // FALL THROUGH - case HAL_PIXEL_FORMAT_RGB_565: - bpp = 2; - break; - } - - return bpp; -} - -void -AnimationFrame::ReadPngFrame(int outputFormat) -{ -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - static const png_byte unused_chunks[] = - { 99, 72, 82, 77, '\0', /* cHRM */ - 104, 73, 83, 84, '\0', /* hIST */ - 105, 67, 67, 80, '\0', /* iCCP */ - 105, 84, 88, 116, '\0', /* iTXt */ - 111, 70, 70, 115, '\0', /* oFFs */ - 112, 67, 65, 76, '\0', /* pCAL */ - 115, 67, 65, 76, '\0', /* sCAL */ - 112, 72, 89, 115, '\0', /* pHYs */ - 115, 66, 73, 84, '\0', /* sBIT */ - 115, 80, 76, 84, '\0', /* sPLT */ - 116, 69, 88, 116, '\0', /* tEXt */ - 116, 73, 77, 69, '\0', /* tIME */ - 122, 84, 88, 116, '\0'}; /* zTXt */ - static const png_byte tRNS_chunk[] = - {116, 82, 78, 83, '\0'}; /* tRNS */ -#endif - - png_structp pngread = png_create_read_struct(PNG_LIBPNG_VER_STRING, - nullptr, nullptr, nullptr); - - if (!pngread) - return; - - png_infop pnginfo = png_create_info_struct(pngread); - - if (!pnginfo) { - png_destroy_read_struct(&pngread, &pnginfo, nullptr); - return; - } - - if (setjmp(png_jmpbuf(pngread))) { - // libpng reported an error and longjumped here. Clean up and return. - png_destroy_read_struct(&pngread, &pnginfo, nullptr); - return; - } - - RawReadState state; - state.start = file->GetData(); - state.length = file->GetDataSize(); - state.offset = 0; - - png_set_read_fn(pngread, &state, RawReader); - -#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED - /* Ignore unused chunks */ - png_set_keep_unknown_chunks(pngread, 1, unused_chunks, - (int)sizeof(unused_chunks)/5); - - /* Ignore the tRNS chunk if we only want opaque output */ - if (outputFormat == HAL_PIXEL_FORMAT_RGB_888 || - outputFormat == HAL_PIXEL_FORMAT_RGB_565) { - png_set_keep_unknown_chunks(pngread, 1, tRNS_chunk, 1); - } -#endif - - png_read_info(pngread, pnginfo); - - png_color_16p colorp; - has_bgcolor = (PNG_INFO_bKGD == png_get_bKGD(pngread, pnginfo, &colorp)); - bgcolor = has_bgcolor ? *colorp : png_color_16(); - width = png_get_image_width(pngread, pnginfo); - height = png_get_image_height(pngread, pnginfo); - - LOG("Decoded %s: %d x %d frame with bgcolor? %s (%#x, %#x, %#x; gray:%#x)", - path, width, height, has_bgcolor ? "yes" : "no", - bgcolor.red, bgcolor.green, bgcolor.blue, bgcolor.gray); - - bytepp = GetFormatBPP(outputFormat); - - switch (outputFormat) { - case HAL_PIXEL_FORMAT_BGRA_8888: - png_set_bgr(pngread); - // FALL THROUGH - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - png_set_filler(pngread, 0xFF, PNG_FILLER_AFTER); - break; - case HAL_PIXEL_FORMAT_RGB_888: - png_set_strip_alpha(pngread); - break; - default: - LOGW("Unknown pixel format %d. Assuming RGB 565.", outputFormat); - // FALL THROUGH - case HAL_PIXEL_FORMAT_RGB_565: - png_set_strip_alpha(pngread); - png_set_read_user_transform_fn(pngread, TransformTo565); - break; - } - - // An extra row is added to give libpng enough space when - // decoding 3/4 bytepp inputs for 2 bytepp output surfaces - buf = (char *)malloc(width * (height + 1) * bytepp); - - vector<char *> rows(height + 1); - uint32_t stride = width * bytepp; - for (uint32_t i = 0; i < height; i++) { - rows[i] = buf + (stride * i); - } - rows[height] = nullptr; - png_set_strip_16(pngread); - png_set_palette_to_rgb(pngread); - png_set_gray_to_rgb(pngread); - png_read_image(pngread, (png_bytepp)&rows.front()); - png_destroy_read_struct(&pngread, &pnginfo, nullptr); -} - -/** - * Return a wchar_t that when used to |wmemset()| an image buffer will - * fill it with the color defined by |color16|. The packed wchar_t - * may comprise one or two pixels depending on |outputFormat|. - */ -static wchar_t -AsBackgroundFill(const png_color_16& color16, int outputFormat) -{ - static_assert(sizeof(wchar_t) == sizeof(uint32_t), - "TODO: support 2-byte wchar_t"); - union { - uint32_t r8g8b8; - struct { - uint8_t b8; - uint8_t g8; - uint8_t r8; - uint8_t x8; - }; - } color; - color.b8 = color16.blue; - color.g8 = color16.green; - color.r8 = color16.red; - color.x8 = 0xFF; - - switch (outputFormat) { - case HAL_PIXEL_FORMAT_RGBA_8888: - case HAL_PIXEL_FORMAT_RGBX_8888: - return color.r8g8b8; - - case HAL_PIXEL_FORMAT_BGRA_8888: - swap(color.r8, color.b8); - return color.r8g8b8; - - case HAL_PIXEL_FORMAT_RGB_565: { - // NB: we could do a higher-quality downsample here, but we - // want the results to be a pixel-perfect match with the fast - // downsample in TransformTo565(). - uint16_t color565 = ((color.r8 & 0xF8) << 8) | - ((color.g8 & 0xFC) << 3) | - ((color.b8 ) >> 3); - return (color565 << 16) | color565; - } - default: - LOGW("Unhandled pixel format %d; falling back on black", outputFormat); - return 0; - } -} - -void -ShowSolidColorFrame(GonkDisplay *aDisplay, - const gralloc_module_t *grallocModule, - int32_t aFormat) -{ - LOGW("Show solid color frame for bootAnim"); - - ANativeWindowBuffer *buffer = aDisplay->DequeueBuffer(); - void *mappedAddress = nullptr; - - if (!buffer) { - LOGW("Failed to get an ANativeWindowBuffer"); - return; - } - - if (!grallocModule->lock(grallocModule, buffer->handle, - GRALLOC_USAGE_SW_READ_NEVER | - GRALLOC_USAGE_SW_WRITE_OFTEN | - GRALLOC_USAGE_HW_FB, - 0, 0, buffer->width, buffer->height, &mappedAddress)) { - // Just show a black solid color frame. - memset(mappedAddress, 0, buffer->height * buffer->stride * GetFormatBPP(aFormat)); - grallocModule->unlock(grallocModule, buffer->handle); - } - - aDisplay->QueueBuffer(buffer); -} - -static void * -AnimationThread(void *) -{ - GonkDisplay *display = GetGonkDisplay(); - int32_t format = display->surfaceformat; - - const hw_module_t *module = nullptr; - if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) { - LOGW("Could not get gralloc module"); - return nullptr; - } - const gralloc_module_t *grmodule = - reinterpret_cast<gralloc_module_t const*>(module); - - ZipReader reader; - if (!reader.OpenArchive("/system/media/bootanimation.zip")) { - LOGW("Could not open boot animation"); - ShowSolidColorFrame(display, grmodule, format); - return nullptr; - } - - const cdir_entry *entry = nullptr; - const local_file_header *file = nullptr; - while ((entry = reader.GetNextEntry(entry))) { - string name = reader.GetEntryName(entry); - if (!name.compare("desc.txt")) { - file = reader.GetLocalEntry(entry); - break; - } - } - - if (!file) { - LOGW("Could not find desc.txt in boot animation"); - ShowSolidColorFrame(display, grmodule, format); - return nullptr; - } - - string descCopy; - descCopy.append(file->GetData(), entry->GetDataSize()); - int32_t width, height, fps; - const char *line = descCopy.c_str(); - const char *end; - bool headerRead = true; - vector<AnimationPart> parts; - bool animPlayed = false; - - /* - * bootanimation.zip - * - * This is the boot animation file format that Android uses. - * It's a zip file with a directories containing png frames - * and a desc.txt that describes how they should be played. - * - * desc.txt contains two types of lines - * 1. [width] [height] [fps] - * There is one of these lines per bootanimation. - * If the width and height are smaller than the screen, - * the frames are centered on a black background. - * XXX: Currently we stretch instead of centering the frame. - * 2. p [count] [pause] [path] - * This describes one animation part. - * Each animation part is played in sequence. - * An animation part contains all the files/frames in the - * directory specified in [path] - * [count] indicates the number of times this part repeats. - * [pause] indicates the number of frames that this part - * should pause for after playing the full sequence but - * before repeating. - */ - - do { - end = strstr(line, "\n"); - - AnimationPart part; - if (headerRead && - sscanf(line, "%d %d %d", &width, &height, &fps) == 3) { - headerRead = false; - } else if (part.ReadFromString(line)) { - parts.push_back(part); - } - } while (end && *(line = end + 1)); - - for (uint32_t i = 0; i < parts.size(); i++) { - AnimationPart &part = parts[i]; - entry = nullptr; - char search[256]; - snprintf(search, sizeof(search), "%s/", part.path); - while ((entry = reader.GetNextEntry(entry))) { - string name = reader.GetEntryName(entry); - if (name.find(search) || - !entry->GetDataSize() || - name.length() >= 256) - continue; - - part.frames.resize(part.frames.size() + 1); - AnimationFrame &frame = part.frames.back(); - strcpy(frame.path, name.c_str()); - frame.file = reader.GetLocalEntry(entry); - } - - sort(part.frames.begin(), part.frames.end()); - } - - long int frameDelayUs = 1000000 / fps; - - for (uint32_t i = 0; i < parts.size(); i++) { - AnimationPart &part = parts[i]; - - int32_t j = 0; - while (sRunAnimation && (!part.count || j++ < part.count)) { - for (uint32_t k = 0; k < part.frames.size(); k++) { - struct timeval tv1, tv2; - gettimeofday(&tv1, nullptr); - AnimationFrame &frame = part.frames[k]; - if (!frame.buf) { - frame.ReadPngFrame(format); - } - - ANativeWindowBuffer *buf = display->DequeueBuffer(); - if (!buf) { - LOGW("Failed to get an ANativeWindowBuffer"); - break; - } - - void *vaddr; - if (grmodule->lock(grmodule, buf->handle, - GRALLOC_USAGE_SW_READ_NEVER | - GRALLOC_USAGE_SW_WRITE_OFTEN | - GRALLOC_USAGE_HW_FB, - 0, 0, width, height, &vaddr)) { - LOGW("Failed to lock buffer_handle_t"); - display->QueueBuffer(buf); - break; - } - - if (frame.has_bgcolor) { - wchar_t bgfill = AsBackgroundFill(frame.bgcolor, format); - wmemset((wchar_t*)vaddr, bgfill, - (buf->height * buf->stride * frame.bytepp) / sizeof(wchar_t)); - } - - if ((uint32_t)buf->height == frame.height && (uint32_t)buf->stride == frame.width) { - memcpy(vaddr, frame.buf, - frame.width * frame.height * frame.bytepp); - } else if ((uint32_t)buf->height >= frame.height && - (uint32_t)buf->width >= frame.width) { - int startx = (buf->width - frame.width) / 2; - int starty = (buf->height - frame.height) / 2; - - int src_stride = frame.width * frame.bytepp; - int dst_stride = buf->stride * frame.bytepp; - - char *src = frame.buf; - char *dst = (char *) vaddr + starty * dst_stride + startx * frame.bytepp; - - for (uint32_t i = 0; i < frame.height; i++) { - memcpy(dst, src, src_stride); - src += src_stride; - dst += dst_stride; - } - } - grmodule->unlock(grmodule, buf->handle); - - gettimeofday(&tv2, nullptr); - - timersub(&tv2, &tv1, &tv2); - - if (tv2.tv_usec < frameDelayUs) { - usleep(frameDelayUs - tv2.tv_usec); - } else { - LOGW("Frame delay is %ld us but decoding took %ld us", - frameDelayUs, tv2.tv_usec); - } - - animPlayed = true; - display->QueueBuffer(buf); - - if (part.count && j >= part.count) { - free(frame.buf); - frame.buf = nullptr; - } - } - usleep(frameDelayUs * part.pause); - } - } - - if (!animPlayed) { - ShowSolidColorFrame(display, grmodule, format); - } - - return nullptr; -} - -namespace mozilla { - -__attribute__ ((visibility ("default"))) -void -StartBootAnimation() -{ - GetGonkDisplay(); // Ensure GonkDisplay exist - sRunAnimation = true; - pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr); -} - -__attribute__ ((visibility ("default"))) -void -StopBootAnimation() -{ - if (sRunAnimation) { - sRunAnimation = false; - pthread_join(sAnimationThread, nullptr); - GetGonkDisplay()->NotifyBootAnimationStopped(); - } -} - -} // namespace mozilla diff --git a/widget/gonk/libdisplay/BootAnimation.h b/widget/gonk/libdisplay/BootAnimation.h deleted file mode 100644 index 9fdc20eca..000000000 --- a/widget/gonk/libdisplay/BootAnimation.h +++ /dev/null @@ -1,30 +0,0 @@ -/* Copyright 2012 Mozilla Foundation and Mozilla contributors - * - * 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 BOOTANIMATION_H -#define BOOTANIMATION_H - -namespace mozilla { - -MOZ_EXPORT __attribute__ ((weak)) -void StartBootAnimation(); - -/* Stop the boot animation if it's still running. */ -MOZ_EXPORT __attribute__ ((weak)) -void StopBootAnimation(); - -} // namespace mozilla - -#endif /* BOOTANIMATION_H */ diff --git a/widget/gonk/libdisplay/DisplaySurface.h b/widget/gonk/libdisplay/DisplaySurface.h deleted file mode 100644 index 398541c49..000000000 --- a/widget/gonk/libdisplay/DisplaySurface.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2013 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_DISPLAY_SURFACE_H -#define ANDROID_SF_DISPLAY_SURFACE_H - -#include <gui/ConsumerBase.h> -#include <system/window.h> -#include <utils/Errors.h> -#include <utils/RefBase.h> -#include <utils/StrongPointer.h> - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class IGraphicBufferProducer; -class String8; - -#if ANDROID_VERSION >= 21 -typedef IGraphicBufferConsumer StreamConsumer; -#else -typedef BufferQueue StreamConsumer; -#endif - -class DisplaySurface : public ConsumerBase { -public: - // beginFrame is called at the beginning of the composition loop, before - // the configuration is known. The DisplaySurface should do anything it - // needs to do to enable HWComposer to decide how to compose the frame. - // We pass in mustRecompose so we can keep VirtualDisplaySurface's state - // machine happy without actually queueing a buffer if nothing has changed. - virtual status_t beginFrame(bool mustRecompose) = 0; - - // prepareFrame is called after the composition configuration is known but - // before composition takes place. The DisplaySurface can use the - // composition type to decide how to manage the flow of buffers between - // GLES and HWC for this frame. - enum CompositionType { - COMPOSITION_UNKNOWN = 0, - COMPOSITION_GLES = 1, - COMPOSITION_HWC = 2, - COMPOSITION_MIXED = COMPOSITION_GLES | COMPOSITION_HWC - }; - virtual status_t prepareFrame(CompositionType compositionType) = 0; - - // Should be called when composition rendering is complete for a frame (but - // eglSwapBuffers hasn't necessarily been called). Required by certain - // older drivers for synchronization. - // TODO: Remove this when we drop support for HWC 1.0. - virtual status_t compositionComplete() = 0; - - // Inform the surface that GLES composition is complete for this frame, and - // the surface should make sure that HWComposer has the correct buffer for - // this frame. Some implementations may only push a new buffer to - // HWComposer if GLES composition took place, others need to push a new - // buffer on every frame. - // - // advanceFrame must be followed by a call to onFrameCommitted before - // advanceFrame may be called again. - virtual status_t advanceFrame() = 0; - - // onFrameCommitted is called after the frame has been committed to the - // hardware composer. The surface collects the release fence for this - // frame's buffer. - virtual void onFrameCommitted() = 0; - - virtual void resizeBuffers(const uint32_t w, const uint32_t h) = 0; - - // 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. - virtual status_t setReleaseFenceFd(int fenceFd) = 0; - - virtual int GetPrevDispAcquireFd() = 0; - - buffer_handle_t lastHandle; - -protected: - DisplaySurface(const sp<StreamConsumer>& sc) -#if ANDROID_VERSION >= 19 - : ConsumerBase(sc, true) -#else - : ConsumerBase(sc) -#endif - , lastHandle(0) - { } - virtual ~DisplaySurface() {} -}; - -// --------------------------------------------------------------------------- -} // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_SF_DISPLAY_SURFACE_H - diff --git a/widget/gonk/libdisplay/FramebufferSurface.cpp b/widget/gonk/libdisplay/FramebufferSurface.cpp deleted file mode 100644 index a289acbb8..000000000 --- a/widget/gonk/libdisplay/FramebufferSurface.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/* - ** - ** Copyright 2012 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> -#if ANDROID_VERSION == 17 -#include <gui/SurfaceTextureClient.h> -#endif -#include <ui/GraphicBuffer.h> - -#include "FramebufferSurface.h" -#include "GraphicBufferAlloc.h" - -#ifndef NUM_FRAMEBUFFER_SURFACE_BUFFERS -#define NUM_FRAMEBUFFER_SURFACE_BUFFERS (2) -#endif - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -/* - * This implements the (main) framebuffer management. This class - * was adapted from the version in SurfaceFlinger - */ -FramebufferSurface::FramebufferSurface(int disp, - uint32_t width, - uint32_t height, - uint32_t format, - const sp<StreamConsumer>& sc) - : DisplaySurface(sc) - , mDisplayType(disp) - , mCurrentBufferSlot(-1) - , mCurrentBuffer(0) -{ - mName = "FramebufferSurface"; - -#if ANDROID_VERSION >= 19 - sp<IGraphicBufferConsumer> consumer = mConsumer; -#else - sp<BufferQueue> consumer = mBufferQueue; - consumer->setSynchronousMode(true); -#endif - consumer->setConsumerName(mName); - consumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB | - GRALLOC_USAGE_HW_RENDER | - GRALLOC_USAGE_HW_COMPOSER); - consumer->setDefaultBufferFormat(format); - consumer->setDefaultBufferSize(width, height); - consumer->setDefaultMaxBufferCount(NUM_FRAMEBUFFER_SURFACE_BUFFERS); -} - -status_t FramebufferSurface::beginFrame(bool /*mustRecompose*/) { - return NO_ERROR; -} - -status_t FramebufferSurface::prepareFrame(CompositionType /*compositionType*/) { - return NO_ERROR; -} - -status_t FramebufferSurface::advanceFrame() { - // Once we remove FB HAL support, we can call nextBuffer() from here - // instead of using onFrameAvailable(). No real benefit, except it'll be - // more like VirtualDisplaySurface. - return NO_ERROR; -} - -status_t FramebufferSurface::nextBuffer(sp<GraphicBuffer>& outBuffer, sp<Fence>& outFence) { - Mutex::Autolock lock(mMutex); - - BufferQueue::BufferItem item; -#if ANDROID_VERSION >= 19 - status_t err = acquireBufferLocked(&item, 0); -#else - status_t err = acquireBufferLocked(&item); -#endif - if (err == BufferQueue::NO_BUFFER_AVAILABLE) { - outBuffer = mCurrentBuffer; - return NO_ERROR; - } else if (err != NO_ERROR) { - ALOGE("error acquiring buffer: %s (%d)", strerror(-err), err); - return err; - } - - // If the BufferQueue has freed and reallocated a buffer in mCurrentSlot - // then we may have acquired the slot we already own. If we had released - // our current buffer before we call acquireBuffer then that release call - // would have returned STALE_BUFFER_SLOT, and we would have called - // freeBufferLocked on that slot. Because the buffer slot has already - // been overwritten with the new buffer all we have to do is skip the - // releaseBuffer call and we should be in the same state we'd be in if we - // had released the old buffer first. - if (mCurrentBufferSlot != BufferQueue::INVALID_BUFFER_SLOT && - item.mBuf != mCurrentBufferSlot) { - // Release the previous buffer. -#if ANDROID_VERSION >= 19 - err = releaseBufferLocked(mCurrentBufferSlot, mCurrentBuffer, - EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); -#else - err = releaseBufferLocked(mCurrentBufferSlot, EGL_NO_DISPLAY, - EGL_NO_SYNC_KHR); -#endif - if (err != NO_ERROR && err != StreamConsumer::STALE_BUFFER_SLOT) { - ALOGE("error releasing buffer: %s (%d)", strerror(-err), err); - return err; - } - } - mCurrentBufferSlot = item.mBuf; - mCurrentBuffer = mSlots[mCurrentBufferSlot].mGraphicBuffer; - outFence = item.mFence; - outBuffer = mCurrentBuffer; - return NO_ERROR; -} - -// Overrides ConsumerBase::onFrameAvailable(), does not call base class impl. -#if ANDROID_VERSION >= 22 -void FramebufferSurface::onFrameAvailable(const ::android::BufferItem &item) { -#else -void FramebufferSurface::onFrameAvailable() { -#endif - sp<GraphicBuffer> buf; - sp<Fence> acquireFence; - status_t err = nextBuffer(buf, acquireFence); - if (err != NO_ERROR) { - ALOGE("error latching nnext FramebufferSurface buffer: %s (%d)", - strerror(-err), err); - return; - } - if (acquireFence.get() && acquireFence->isValid()) - mPrevFBAcquireFence = new Fence(acquireFence->dup()); - else - mPrevFBAcquireFence = Fence::NO_FENCE; - - lastHandle = buf->handle; -} - -void FramebufferSurface::freeBufferLocked(int slotIndex) { - ConsumerBase::freeBufferLocked(slotIndex); - if (slotIndex == mCurrentBufferSlot) { - mCurrentBufferSlot = BufferQueue::INVALID_BUFFER_SLOT; - } -} - -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) { -#if ANDROID_VERSION >= 19 - status_t err = addReleaseFence(mCurrentBufferSlot, mCurrentBuffer, fence); -#else - status_t err = addReleaseFence(mCurrentBufferSlot, fence); -#endif - ALOGE_IF(err, "setReleaseFenceFd: failed to add the fence: %s (%d)", - strerror(-err), err); - } - } - return err; -} - -int FramebufferSurface::GetPrevDispAcquireFd() { - if (mPrevFBAcquireFence.get() && mPrevFBAcquireFence->isValid()) { - return mPrevFBAcquireFence->dup(); - } - return -1; -} - -void FramebufferSurface::onFrameCommitted() { - // XXX This role is almost same to setReleaseFenceFd(). -} - -status_t FramebufferSurface::compositionComplete() -{ - // Actual implementaiton is in GonkDisplay::SwapBuffers() - // XXX need to move that to here. - return NO_ERROR; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- diff --git a/widget/gonk/libdisplay/FramebufferSurface.h b/widget/gonk/libdisplay/FramebufferSurface.h deleted file mode 100644 index c1cc84272..000000000 --- a/widget/gonk/libdisplay/FramebufferSurface.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * 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 "DisplaySurface.h" - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class Rect; -class String8; - -// --------------------------------------------------------------------------- - -class FramebufferSurface : public DisplaySurface { -public: - FramebufferSurface(int disp, uint32_t width, uint32_t height, uint32_t format, const sp<StreamConsumer>& sc); - - // From DisplaySurface - virtual status_t beginFrame(bool mustRecompose); - virtual status_t prepareFrame(CompositionType compositionType); - virtual status_t compositionComplete(); - virtual status_t advanceFrame(); - virtual void onFrameCommitted(); - // Cannot resize a buffers in a FramebufferSurface. Only works with virtual - // displays. - virtual void resizeBuffers(const uint32_t /*w*/, const uint32_t /*h*/) { }; - - // 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); - - virtual int GetPrevDispAcquireFd(); - -private: - virtual ~FramebufferSurface() { }; // this class cannot be overloaded - -#if ANDROID_VERSION >= 22 - virtual void onFrameAvailable(const ::android::BufferItem &item); -#else - virtual void onFrameAvailable(); -#endif - 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); - - // mDisplayType must match one of the HWC display types - int mDisplayType; - - // 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. - int mCurrentBufferSlot; - - // mCurrentBuffer is the current buffer or NULL to indicate that there is - // no current buffer. - sp<GraphicBuffer> mCurrentBuffer; - - android::sp<android::Fence> mPrevFBAcquireFence; -}; - -// --------------------------------------------------------------------------- -}; // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_SF_FRAMEBUFFER_SURFACE_H - diff --git a/widget/gonk/libdisplay/GonkDisplay.h b/widget/gonk/libdisplay/GonkDisplay.h deleted file mode 100644 index 96978a6e9..000000000 --- a/widget/gonk/libdisplay/GonkDisplay.h +++ /dev/null @@ -1,91 +0,0 @@ -/* Copyright 2013 Mozilla Foundation and Mozilla contributors - * - * 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 GONKDISPLAY_H -#define GONKDISPLAY_H - -#include <system/window.h> -#include <utils/StrongPointer.h> -#include "mozilla/Types.h" - -namespace android { -class DisplaySurface; -class IGraphicBufferProducer; -} - -namespace mozilla { - -typedef void * EGLDisplay; -typedef void * EGLSurface; - -class MOZ_EXPORT GonkDisplay { -public: - /** - * This enum is for types of display. DISPLAY_PRIMARY refers to the default - * built-in display, DISPLAY_EXTERNAL refers to displays connected with - * HDMI, and DISPLAY_VIRTUAL are displays which makes composited output - * available within the system. Currently, displays of external are detected - * via the hotplug detection in HWC, and displays of virtual are connected - * via Wifi Display. - */ - enum DisplayType { - DISPLAY_PRIMARY, - DISPLAY_EXTERNAL, - DISPLAY_VIRTUAL, - NUM_DISPLAY_TYPES - }; - - struct NativeData { - android::sp<ANativeWindow> mNativeWindow; -#if ANDROID_VERSION >= 17 - android::sp<android::DisplaySurface> mDisplaySurface; -#endif - float mXdpi; - }; - - virtual void SetEnabled(bool enabled) = 0; - - typedef void (*OnEnabledCallbackType)(bool enabled); - - virtual void OnEnabled(OnEnabledCallbackType callback) = 0; - - virtual void* GetHWCDevice() = 0; - - /** - * Only GonkDisplayICS uses arguments. - */ - virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur) = 0; - - virtual ANativeWindowBuffer* DequeueBuffer() = 0; - - virtual bool QueueBuffer(ANativeWindowBuffer* buf) = 0; - - virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) = 0; - - virtual NativeData GetNativeData( - GonkDisplay::DisplayType aDisplayType, - android::IGraphicBufferProducer* aSink = nullptr) = 0; - - virtual void NotifyBootAnimationStopped() = 0; - - float xdpi; - int32_t surfaceformat; -}; - -MOZ_EXPORT __attribute__ ((weak)) -GonkDisplay* GetGonkDisplay(); - -} -#endif /* GONKDISPLAY_H */ diff --git a/widget/gonk/libdisplay/GonkDisplayJB.cpp b/widget/gonk/libdisplay/GonkDisplayJB.cpp deleted file mode 100644 index 197b85a47..000000000 --- a/widget/gonk/libdisplay/GonkDisplayJB.cpp +++ /dev/null @@ -1,461 +0,0 @@ -/* Copyright 2013 Mozilla Foundation and Mozilla contributors - * - * 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 "GonkDisplayJB.h" -#if ANDROID_VERSION == 17 -#include <gui/SurfaceTextureClient.h> -#else -#include <gui/Surface.h> -#include <gui/GraphicBufferAlloc.h> -#endif - -#include <hardware/hardware.h> -#include <hardware/hwcomposer.h> -#include <hardware/power.h> -#include <suspend/autosuspend.h> - -#if ANDROID_VERSION >= 19 -#include "VirtualDisplaySurface.h" -#endif -#include "FramebufferSurface.h" -#if ANDROID_VERSION == 17 -#include "GraphicBufferAlloc.h" -#endif -#include "mozilla/Assertions.h" - -#define DEFAULT_XDPI 75.0 - -using namespace android; - -namespace mozilla { - -static GonkDisplayJB* sGonkDisplay = nullptr; - -GonkDisplayJB::GonkDisplayJB() - : mModule(nullptr) - , mFBModule(nullptr) - , mHwc(nullptr) - , mFBDevice(nullptr) - , mPowerModule(nullptr) - , mList(nullptr) - , mWidth(0) - , mHeight(0) - , mEnabledCallback(nullptr) -{ - int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &mFBModule); - ALOGW_IF(err, "%s module not found", GRALLOC_HARDWARE_MODULE_ID); - if (!err) { - err = framebuffer_open(mFBModule, &mFBDevice); - ALOGW_IF(err, "could not open framebuffer"); - } - - if (!err && mFBDevice) { - mWidth = mFBDevice->width; - mHeight = mFBDevice->height; - xdpi = mFBDevice->xdpi; - /* The emulator actually reports RGBA_8888, but EGL doesn't return - * any matching configuration. We force RGBX here to fix it. */ - surfaceformat = HAL_PIXEL_FORMAT_RGBX_8888; - } - - err = hw_get_module(HWC_HARDWARE_MODULE_ID, &mModule); - ALOGW_IF(err, "%s module not found", HWC_HARDWARE_MODULE_ID); - if (!err) { - err = hwc_open_1(mModule, &mHwc); - ALOGE_IF(err, "%s device failed to initialize (%s)", - HWC_HARDWARE_COMPOSER, strerror(-err)); - } - - /* Fallback on the FB rendering path instead of trying to support HWC 1.0 */ - if (!err && mHwc->common.version == HWC_DEVICE_API_VERSION_1_0) { - hwc_close_1(mHwc); - mHwc = nullptr; - } - - if (!err && mHwc) { - if (mFBDevice) { - framebuffer_close(mFBDevice); - mFBDevice = nullptr; - } - - int32_t values[3]; - const uint32_t attrs[] = { - HWC_DISPLAY_WIDTH, - HWC_DISPLAY_HEIGHT, - HWC_DISPLAY_DPI_X, - HWC_DISPLAY_NO_ATTRIBUTE - }; - mHwc->getDisplayAttributes(mHwc, 0, 0, attrs, values); - - mWidth = values[0]; - mHeight = values[1]; - xdpi = values[2] / 1000.0f; - surfaceformat = HAL_PIXEL_FORMAT_RGBA_8888; - } - - err = hw_get_module(POWER_HARDWARE_MODULE_ID, - (hw_module_t const**)&mPowerModule); - if (!err) - mPowerModule->init(mPowerModule); - ALOGW_IF(err, "Couldn't load %s module (%s)", POWER_HARDWARE_MODULE_ID, strerror(-err)); - - mAlloc = new GraphicBufferAlloc(); - - CreateFramebufferSurface(mSTClient, mDispSurface, mWidth, mHeight); - - mList = (hwc_display_contents_1_t *)calloc(1, sizeof(*mList) + (sizeof(hwc_layer_1_t)*2)); - - uint32_t usage = GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_COMPOSER; - if (mFBDevice) { - // If device uses fb, they can not use single buffer for boot animation - mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_BUFFER_COUNT, 2); - mSTClient->perform(mSTClient.get(), NATIVE_WINDOW_SET_USAGE, usage); - } else if (mHwc) { - PowerOnDisplay(HWC_DISPLAY_PRIMARY); - // For devices w/ hwc v1.0 or no hwc, this buffer can not be created, - // only create this buffer for devices w/ hwc version > 1.0. - CreateFramebufferSurface(mBootAnimSTClient, mBootAnimDispSurface, mWidth, mHeight); - } -} - -GonkDisplayJB::~GonkDisplayJB() -{ - if (mHwc) - hwc_close_1(mHwc); - if (mFBDevice) - framebuffer_close(mFBDevice); - free(mList); -} - -void -GonkDisplayJB::CreateFramebufferSurface(android::sp<ANativeWindow>& aNativeWindow, - android::sp<android::DisplaySurface>& aDisplaySurface, - uint32_t aWidth, - uint32_t aHeight) -{ -#if ANDROID_VERSION >= 21 - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - BufferQueue::createBufferQueue(&producer, &consumer, mAlloc); -#elif ANDROID_VERSION >= 19 - sp<BufferQueue> consumer = new BufferQueue(mAlloc); - sp<IGraphicBufferProducer> producer = consumer; -#elif ANDROID_VERSION >= 18 - sp<BufferQueue> consumer = new BufferQueue(true, mAlloc); - sp<IGraphicBufferProducer> producer = consumer; -#else - sp<BufferQueue> consumer = new BufferQueue(true, mAlloc); -#endif - - aDisplaySurface = new FramebufferSurface(0, aWidth, aHeight, surfaceformat, consumer); - -#if ANDROID_VERSION == 17 - aNativeWindow = new SurfaceTextureClient( - static_cast<sp<ISurfaceTexture>>(aDisplaySurface->getBufferQueue())); -#else - aNativeWindow = new Surface(producer); -#endif -} - -void -GonkDisplayJB::CreateVirtualDisplaySurface(android::IGraphicBufferProducer* aSink, - android::sp<ANativeWindow>& aNativeWindow, - android::sp<android::DisplaySurface>& aDisplaySurface) -{ -#if ANDROID_VERSION >= 21 - sp<IGraphicBufferProducer> producer; - sp<IGraphicBufferConsumer> consumer; - BufferQueue::createBufferQueue(&producer, &consumer, mAlloc); -#elif ANDROID_VERSION >= 19 - sp<BufferQueue> consumer = new BufferQueue(mAlloc); - sp<IGraphicBufferProducer> producer = consumer; -#endif - -#if ANDROID_VERSION >= 19 - sp<VirtualDisplaySurface> virtualDisplay; - virtualDisplay = new VirtualDisplaySurface(-1, aSink, producer, consumer, String8("VirtualDisplaySurface")); - aDisplaySurface = virtualDisplay; - aNativeWindow = new Surface(virtualDisplay); -#endif -} - -void -GonkDisplayJB::SetEnabled(bool enabled) -{ - if (enabled) { - autosuspend_disable(); - mPowerModule->setInteractive(mPowerModule, true); - } - - if (!enabled && mEnabledCallback) { - mEnabledCallback(enabled); - } - -#if ANDROID_VERSION >= 21 - if (mHwc) { - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) { - mHwc->setPowerMode(mHwc, HWC_DISPLAY_PRIMARY, - (enabled ? HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF)); - } else { - mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled); - } - } else if (mFBDevice && mFBDevice->enableScreen) { - mFBDevice->enableScreen(mFBDevice, enabled); - } -#else - if (mHwc && mHwc->blank) { - mHwc->blank(mHwc, HWC_DISPLAY_PRIMARY, !enabled); - } else if (mFBDevice && mFBDevice->enableScreen) { - mFBDevice->enableScreen(mFBDevice, enabled); - } -#endif - - if (enabled && mEnabledCallback) { - mEnabledCallback(enabled); - } - - if (!enabled) { - autosuspend_enable(); - mPowerModule->setInteractive(mPowerModule, false); - } -} - -void -GonkDisplayJB::OnEnabled(OnEnabledCallbackType callback) -{ - mEnabledCallback = callback; -} - -void* -GonkDisplayJB::GetHWCDevice() -{ - return mHwc; -} - -bool -GonkDisplayJB::SwapBuffers(EGLDisplay dpy, EGLSurface sur) -{ - // Should be called when composition rendering is complete for a frame. - // Only HWC v1.0 needs this call. - // HWC > v1.0 case, do not call compositionComplete(). - // mFBDevice is present only when HWC is v1.0. - if (mFBDevice && mFBDevice->compositionComplete) { - mFBDevice->compositionComplete(mFBDevice); - } - return Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd()); -} - -bool -GonkDisplayJB::Post(buffer_handle_t buf, int fence) -{ - if (!mHwc) { - if (fence >= 0) - close(fence); - return !mFBDevice->post(mFBDevice, buf); - } - - hwc_display_contents_1_t *displays[HWC_NUM_DISPLAY_TYPES] = {NULL}; - const hwc_rect_t r = { 0, 0, static_cast<int>(mWidth), static_cast<int>(mHeight) }; - displays[HWC_DISPLAY_PRIMARY] = mList; - mList->retireFenceFd = -1; - mList->numHwLayers = 2; - mList->flags = HWC_GEOMETRY_CHANGED; -#if ANDROID_VERSION >= 18 - mList->outbuf = nullptr; - mList->outbufAcquireFenceFd = -1; -#endif - mList->hwLayers[0].compositionType = HWC_FRAMEBUFFER; - mList->hwLayers[0].hints = 0; - /* Skip this layer so the hwc module doesn't complain about null handles */ - mList->hwLayers[0].flags = HWC_SKIP_LAYER; - mList->hwLayers[0].backgroundColor = {0}; - mList->hwLayers[0].acquireFenceFd = -1; - mList->hwLayers[0].releaseFenceFd = -1; - /* hwc module checks displayFrame even though it shouldn't */ - mList->hwLayers[0].displayFrame = r; - mList->hwLayers[1].compositionType = HWC_FRAMEBUFFER_TARGET; - mList->hwLayers[1].hints = 0; - mList->hwLayers[1].flags = 0; - mList->hwLayers[1].handle = buf; - mList->hwLayers[1].transform = 0; - mList->hwLayers[1].blending = HWC_BLENDING_NONE; -#if ANDROID_VERSION >= 19 - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_3) { - mList->hwLayers[1].sourceCropf.left = 0; - mList->hwLayers[1].sourceCropf.top = 0; - mList->hwLayers[1].sourceCropf.right = mWidth; - mList->hwLayers[1].sourceCropf.bottom = mHeight; - } else { - mList->hwLayers[1].sourceCrop = r; - } -#else - mList->hwLayers[1].sourceCrop = r; -#endif - mList->hwLayers[1].displayFrame = r; - mList->hwLayers[1].visibleRegionScreen.numRects = 1; - mList->hwLayers[1].visibleRegionScreen.rects = &mList->hwLayers[1].displayFrame; - mList->hwLayers[1].acquireFenceFd = fence; - mList->hwLayers[1].releaseFenceFd = -1; -#if ANDROID_VERSION >= 18 - mList->hwLayers[1].planeAlpha = 0xFF; -#endif - mHwc->prepare(mHwc, HWC_NUM_DISPLAY_TYPES, displays); - int err = mHwc->set(mHwc, HWC_NUM_DISPLAY_TYPES, displays); - - if (!mBootAnimDispSurface.get()) { - mDispSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd); - } else { - mBootAnimDispSurface->setReleaseFenceFd(mList->hwLayers[1].releaseFenceFd); - } - - if (mList->retireFenceFd >= 0) - close(mList->retireFenceFd); - return !err; -} - -ANativeWindowBuffer* -GonkDisplayJB::DequeueBuffer() -{ - // Check for bootAnim or normal display flow. - sp<ANativeWindow> nativeWindow = - !mBootAnimSTClient.get() ? mSTClient : mBootAnimSTClient; - - ANativeWindowBuffer *buf; - int fenceFd = -1; - nativeWindow->dequeueBuffer(nativeWindow.get(), &buf, &fenceFd); - sp<Fence> fence(new Fence(fenceFd)); -#if ANDROID_VERSION == 17 - fence->waitForever(1000, "GonkDisplayJB_DequeueBuffer"); - // 1000 is what Android uses. It is a warning timeout in ms. - // This timeout was removed in ANDROID_VERSION 18. -#else - fence->waitForever("GonkDisplayJB_DequeueBuffer"); -#endif - return buf; -} - -bool -GonkDisplayJB::QueueBuffer(ANativeWindowBuffer* buf) -{ - bool success = false; - int error = DoQueueBuffer(buf); - // Check for bootAnim or normal display flow. - if (!mBootAnimSTClient.get()) { - success = Post(mDispSurface->lastHandle, mDispSurface->GetPrevDispAcquireFd()); - } else { - success = Post(mBootAnimDispSurface->lastHandle, mBootAnimDispSurface->GetPrevDispAcquireFd()); - } - return error == 0 && success; -} - -int -GonkDisplayJB::DoQueueBuffer(ANativeWindowBuffer* buf) -{ - int error = 0; - // Check for bootAnim or normal display flow. - if (!mBootAnimSTClient.get()) { - error = mSTClient->queueBuffer(mSTClient.get(), buf, -1); - } else { - error = mBootAnimSTClient->queueBuffer(mBootAnimSTClient.get(), buf, -1); - } - return error; -} - -void -GonkDisplayJB::UpdateDispSurface(EGLDisplay dpy, EGLSurface sur) -{ - if (sur != EGL_NO_SURFACE) { - eglSwapBuffers(dpy, sur); - } else { - // When BasicCompositor is used as Compositor, - // EGLSurface does not exit. - ANativeWindowBuffer* buf = DequeueBuffer(); - DoQueueBuffer(buf); - } -} - -void -GonkDisplayJB::NotifyBootAnimationStopped() -{ - if (mBootAnimSTClient.get()) { - mBootAnimSTClient = nullptr; - mBootAnimDispSurface = nullptr; - } -} - -void -GonkDisplayJB::PowerOnDisplay(int aDpy) -{ - MOZ_ASSERT(mHwc); -#if ANDROID_VERSION >= 21 - if (mHwc->common.version >= HWC_DEVICE_API_VERSION_1_4) { - mHwc->setPowerMode(mHwc, aDpy, HWC_POWER_MODE_NORMAL); - } else { - mHwc->blank(mHwc, aDpy, 0); - } -#else - mHwc->blank(mHwc, aDpy, 0); -#endif -} - -GonkDisplay::NativeData -GonkDisplayJB::GetNativeData(GonkDisplay::DisplayType aDisplayType, - android::IGraphicBufferProducer* aSink) -{ - NativeData data; - - if (aDisplayType == DISPLAY_PRIMARY) { - data.mNativeWindow = mSTClient; - data.mDisplaySurface = mDispSurface; - data.mXdpi = xdpi; - } else if (aDisplayType == DISPLAY_EXTERNAL) { - int32_t values[3]; - const uint32_t attrs[] = { - HWC_DISPLAY_WIDTH, - HWC_DISPLAY_HEIGHT, - HWC_DISPLAY_DPI_X, - HWC_DISPLAY_NO_ATTRIBUTE - }; - mHwc->getDisplayAttributes(mHwc, aDisplayType, 0, attrs, values); - int width = values[0]; - int height = values[1]; - // FIXME!! values[2] returns 0 for external display, which doesn't - // sound right, Bug 1169176 is the follow-up bug for this issue. - data.mXdpi = values[2] ? values[2] / 1000.f : DEFAULT_XDPI; - PowerOnDisplay(HWC_DISPLAY_EXTERNAL); - CreateFramebufferSurface(data.mNativeWindow, - data.mDisplaySurface, - width, - height); - } else if (aDisplayType == DISPLAY_VIRTUAL) { - data.mXdpi = xdpi; - CreateVirtualDisplaySurface(aSink, - data.mNativeWindow, - data.mDisplaySurface); - } - - return data; -} - -__attribute__ ((visibility ("default"))) -GonkDisplay* -GetGonkDisplay() -{ - if (!sGonkDisplay) - sGonkDisplay = new GonkDisplayJB(); - return sGonkDisplay; -} - -} // namespace mozilla diff --git a/widget/gonk/libdisplay/GonkDisplayJB.h b/widget/gonk/libdisplay/GonkDisplayJB.h deleted file mode 100644 index 60bcdffc4..000000000 --- a/widget/gonk/libdisplay/GonkDisplayJB.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2013 Mozilla Foundation and Mozilla contributors - * - * 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 GONKDISPLAYJB_H -#define GONKDISPLAYJB_H - -#include "DisplaySurface.h" -#include "GonkDisplay.h" -#include "hardware/hwcomposer.h" -#include "hardware/power.h" -#include "ui/Fence.h" -#include "utils/RefBase.h" - -namespace mozilla { - -class MOZ_EXPORT GonkDisplayJB : public GonkDisplay { -public: - GonkDisplayJB(); - ~GonkDisplayJB(); - - virtual void SetEnabled(bool enabled); - - virtual void OnEnabled(OnEnabledCallbackType callback); - - virtual void* GetHWCDevice(); - - virtual bool SwapBuffers(EGLDisplay dpy, EGLSurface sur); - - virtual ANativeWindowBuffer* DequeueBuffer(); - - virtual bool QueueBuffer(ANativeWindowBuffer* buf); - - virtual void UpdateDispSurface(EGLDisplay dpy, EGLSurface sur); - - bool Post(buffer_handle_t buf, int fence); - - virtual NativeData GetNativeData( - GonkDisplay::DisplayType aDisplayType, - android::IGraphicBufferProducer* aSink = nullptr); - - virtual void NotifyBootAnimationStopped(); - -private: - void CreateFramebufferSurface(android::sp<ANativeWindow>& aNativeWindow, - android::sp<android::DisplaySurface>& aDisplaySurface, - uint32_t aWidth, uint32_t aHeight); - void CreateVirtualDisplaySurface(android::IGraphicBufferProducer* aSink, - android::sp<ANativeWindow>& aNativeWindow, - android::sp<android::DisplaySurface>& aDisplaySurface); - - void PowerOnDisplay(int aDpy); - - int DoQueueBuffer(ANativeWindowBuffer* buf); - - hw_module_t const* mModule; - hw_module_t const* mFBModule; - hwc_composer_device_1_t* mHwc; - framebuffer_device_t* mFBDevice; - power_module_t* mPowerModule; - android::sp<android::DisplaySurface> mDispSurface; - android::sp<ANativeWindow> mSTClient; - android::sp<android::DisplaySurface> mBootAnimDispSurface; - android::sp<ANativeWindow> mBootAnimSTClient; - android::sp<android::IGraphicBufferAlloc> mAlloc; - hwc_display_contents_1_t* mList; - uint32_t mWidth; - uint32_t mHeight; - OnEnabledCallbackType mEnabledCallback; -}; - -} - -#endif /* GONKDISPLAYJB_H */ diff --git a/widget/gonk/libdisplay/GraphicBufferAlloc.cpp b/widget/gonk/libdisplay/GraphicBufferAlloc.cpp deleted file mode 100644 index 5722b7fe3..000000000 --- a/widget/gonk/libdisplay/GraphicBufferAlloc.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - ** - ** Copyright 2012 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 <cutils/log.h> - -#include <ui/GraphicBuffer.h> - -#include "GraphicBufferAlloc.h" - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -GraphicBufferAlloc::GraphicBufferAlloc() { -} - -GraphicBufferAlloc::~GraphicBufferAlloc() { -} - -sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h, - PixelFormat format, uint32_t usage, status_t* error) { - sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage)); - status_t err = graphicBuffer->initCheck(); - *error = err; - if (err != 0 || graphicBuffer->handle == 0) { - if (err == NO_MEMORY) { - GraphicBuffer::dumpAllocationsToSystemLog(); - } - ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) " - "failed (%s), handle=%p", - w, h, strerror(-err), graphicBuffer->handle); - return 0; - } - return graphicBuffer; -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- diff --git a/widget/gonk/libdisplay/GraphicBufferAlloc.h b/widget/gonk/libdisplay/GraphicBufferAlloc.h deleted file mode 100644 index b08750c2f..000000000 --- a/widget/gonk/libdisplay/GraphicBufferAlloc.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2012 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_GRAPHIC_BUFFER_ALLOC_H -#define ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H - -#include <stdint.h> -#include <sys/types.h> - -#include <gui/IGraphicBufferAlloc.h> -#include <ui/PixelFormat.h> -#include <utils/Errors.h> - -namespace android { -// --------------------------------------------------------------------------- - -class GraphicBuffer; - -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); -}; - - -// --------------------------------------------------------------------------- -}; // namespace android - -#endif // ANDROID_SF_GRAPHIC_BUFFER_ALLOC_H diff --git a/widget/gonk/libdisplay/VirtualDisplaySurface.cpp b/widget/gonk/libdisplay/VirtualDisplaySurface.cpp deleted file mode 100644 index 746707885..000000000 --- a/widget/gonk/libdisplay/VirtualDisplaySurface.cpp +++ /dev/null @@ -1,635 +0,0 @@ -/* - * Copyright 2013 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. - */ - -// #define LOG_NDEBUG 0 -#include "VirtualDisplaySurface.h" - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -#if defined(FORCE_HWC_COPY_FOR_VIRTUAL_DISPLAYS) -static const bool sForceHwcCopy = true; -#else -static const bool sForceHwcCopy = false; -#endif - -#define VDS_LOGE(msg, ...) ALOGE("[%s] " msg, \ - mDisplayName.string(), ##__VA_ARGS__) -#define VDS_LOGW_IF(cond, msg, ...) ALOGW_IF(cond, "[%s] " msg, \ - mDisplayName.string(), ##__VA_ARGS__) -#define VDS_LOGV(msg, ...) ALOGV("[%s] " msg, \ - mDisplayName.string(), ##__VA_ARGS__) - -__attribute__((unused)) -static const char* dbgCompositionTypeStr(DisplaySurface::CompositionType type) { - switch (type) { - case DisplaySurface::COMPOSITION_UNKNOWN: return "UNKNOWN"; - case DisplaySurface::COMPOSITION_GLES: return "GLES"; - case DisplaySurface::COMPOSITION_HWC: return "HWC"; - case DisplaySurface::COMPOSITION_MIXED: return "MIXED"; - default: return "<INVALID>"; - } -} - -VirtualDisplaySurface::VirtualDisplaySurface(int32_t dispId, - const sp<IGraphicBufferProducer>& sink, - const sp<IGraphicBufferProducer>& bqProducer, - const sp<StreamConsumer>& bqConsumer, - const String8& name) -: DisplaySurface(bqConsumer), - mDisplayId(dispId), - mDisplayName(name), - mOutputUsage(GRALLOC_USAGE_HW_COMPOSER), - mProducerSlotSource(0), - mDbgState(DBG_STATE_IDLE), - mDbgLastCompositionType(COMPOSITION_UNKNOWN), - mMustRecompose(false) -{ - mSource[SOURCE_SINK] = sink; - mSource[SOURCE_SCRATCH] = bqProducer; - - resetPerFrameState(); - - int sinkWidth, sinkHeight; - sink->query(NATIVE_WINDOW_WIDTH, &sinkWidth); - sink->query(NATIVE_WINDOW_HEIGHT, &sinkHeight); - mSinkBufferWidth = sinkWidth; - mSinkBufferHeight = sinkHeight; - - // Pick the buffer format to request from the sink when not rendering to it - // with GLES. If the consumer needs CPU access, use the default format - // set by the consumer. Otherwise allow gralloc to decide the format based - // on usage bits. - int sinkUsage; - sink->query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, &sinkUsage); - if (sinkUsage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { - int sinkFormat; - sink->query(NATIVE_WINDOW_FORMAT, &sinkFormat); - mDefaultOutputFormat = sinkFormat; - } else { - mDefaultOutputFormat = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED; - } - mOutputFormat = mDefaultOutputFormat; - - ConsumerBase::mName = String8::format("VDS: %s", mDisplayName.string()); - mConsumer->setConsumerName(ConsumerBase::mName); - mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_COMPOSER); - mConsumer->setDefaultBufferSize(sinkWidth, sinkHeight); - mConsumer->setDefaultMaxBufferCount(2); -} - -VirtualDisplaySurface::~VirtualDisplaySurface() { -} - -status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) { - if (mDisplayId < 0) - return NO_ERROR; - - mMustRecompose = mustRecompose; - - VDS_LOGW_IF(mDbgState != DBG_STATE_IDLE, - "Unexpected beginFrame() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_BEGUN; - - return refreshOutputBuffer(); -} - -status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) { - if (mDisplayId < 0) - return NO_ERROR; - - VDS_LOGW_IF(mDbgState != DBG_STATE_BEGUN, - "Unexpected prepareFrame() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_PREPARED; - - mCompositionType = compositionType; - if (sForceHwcCopy && mCompositionType == COMPOSITION_GLES) { - // Some hardware can do RGB->YUV conversion more efficiently in hardware - // controlled by HWC than in hardware controlled by the video encoder. - // Forcing GLES-composed frames to go through an extra copy by the HWC - // allows the format conversion to happen there, rather than passing RGB - // directly to the consumer. - // - // On the other hand, when the consumer prefers RGB or can consume RGB - // inexpensively, this forces an unnecessary copy. - mCompositionType = COMPOSITION_MIXED; - } - - if (mCompositionType != mDbgLastCompositionType) { - VDS_LOGV("prepareFrame: composition type changed to %s", - dbgCompositionTypeStr(mCompositionType)); - mDbgLastCompositionType = mCompositionType; - } - - if (mCompositionType != COMPOSITION_GLES && - (mOutputFormat != mDefaultOutputFormat || - mOutputUsage != GRALLOC_USAGE_HW_COMPOSER)) { - // We must have just switched from GLES-only to MIXED or HWC - // composition. Stop using the format and usage requested by the GLES - // driver; they may be suboptimal when HWC is writing to the output - // buffer. For example, if the output is going to a video encoder, and - // HWC can write directly to YUV, some hardware can skip a - // memory-to-memory RGB-to-YUV conversion step. - // - // If we just switched *to* GLES-only mode, we'll change the - // format/usage and get a new buffer when the GLES driver calls - // dequeueBuffer(). - mOutputFormat = mDefaultOutputFormat; - mOutputUsage = GRALLOC_USAGE_HW_COMPOSER; - refreshOutputBuffer(); - } - - return NO_ERROR; -} - -status_t VirtualDisplaySurface::compositionComplete() { - return NO_ERROR; -} - -status_t VirtualDisplaySurface::advanceFrame() { - return NO_ERROR; - -// XXX Add HWC support - -#if 0 - if (mDisplayId < 0) - return NO_ERROR; - - if (mCompositionType == COMPOSITION_HWC) { - VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, - "Unexpected advanceFrame() in %s state on HWC frame", - dbgStateStr()); - } else { - VDS_LOGW_IF(mDbgState != DBG_STATE_GLES_DONE, - "Unexpected advanceFrame() in %s state on GLES/MIXED frame", - dbgStateStr()); - } - mDbgState = DBG_STATE_HWC; - - if (mOutputProducerSlot < 0 || - (mCompositionType != COMPOSITION_HWC && mFbProducerSlot < 0)) { - // Last chance bailout if something bad happened earlier. For example, - // in a GLES configuration, if the sink disappears then dequeueBuffer - // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger - // will soldier on. So we end up here without a buffer. There should - // be lots of scary messages in the log just before this. - VDS_LOGE("advanceFrame: no buffer, bailing out"); - return NO_MEMORY; - } - - sp<GraphicBuffer> fbBuffer = mFbProducerSlot >= 0 ? - mProducerBuffers[mFbProducerSlot] : sp<GraphicBuffer>(NULL); - sp<GraphicBuffer> outBuffer = mProducerBuffers[mOutputProducerSlot]; - VDS_LOGV("advanceFrame: fb=%d(%p) out=%d(%p)", - mFbProducerSlot, fbBuffer.get(), - mOutputProducerSlot, outBuffer.get()); - - // At this point we know the output buffer acquire fence, - // so update HWC state with it. - mHwc.setOutputBuffer(mDisplayId, mOutputFence, outBuffer); - - status_t result = NO_ERROR; - if (fbBuffer != NULL) { - result = mHwc.fbPost(mDisplayId, mFbFence, fbBuffer); - } - - return result; -#endif -} - -void VirtualDisplaySurface::onFrameCommitted() { - return; - -// XXX Add HWC support - -#if 0 - if (mDisplayId < 0) - return; - - VDS_LOGW_IF(mDbgState != DBG_STATE_HWC, - "Unexpected onFrameCommitted() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_IDLE; - - sp<Fence> fbFence = mHwc.getAndResetReleaseFence(mDisplayId); - if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) { - // release the scratch buffer back to the pool - Mutex::Autolock lock(mMutex); - int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, mFbProducerSlot); - VDS_LOGV("onFrameCommitted: release scratch sslot=%d", sslot); - addReleaseFenceLocked(sslot, mProducerBuffers[mFbProducerSlot], fbFence); - releaseBufferLocked(sslot, mProducerBuffers[mFbProducerSlot], - EGL_NO_DISPLAY, EGL_NO_SYNC_KHR); - } - - if (mOutputProducerSlot >= 0) { - int sslot = mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot); - QueueBufferOutput qbo; - sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId); - VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot); - if (mMustRecompose) { - status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot, - QueueBufferInput( - systemTime(), false /* isAutoTimestamp */, - Rect(mSinkBufferWidth, mSinkBufferHeight), - NATIVE_WINDOW_SCALING_MODE_FREEZE, 0 /* transform */, - true /* async*/, - outFence), - &qbo); - if (result == NO_ERROR) { - updateQueueBufferOutput(qbo); - } - } else { - // If the surface hadn't actually been updated, then we only went - // through the motions of updating the display to keep our state - // machine happy. We cancel the buffer to avoid triggering another - // re-composition and causing an infinite loop. - mSource[SOURCE_SINK]->cancelBuffer(sslot, outFence); - } - } - - resetPerFrameState(); -#endif -} - -void VirtualDisplaySurface::resizeBuffers(const uint32_t w, const uint32_t h) { - uint32_t tmpW, tmpH, transformHint, numPendingBuffers; - mQueueBufferOutput.deflate(&tmpW, &tmpH, &transformHint, &numPendingBuffers); - mQueueBufferOutput.inflate(w, h, transformHint, numPendingBuffers); - - mSinkBufferWidth = w; - mSinkBufferHeight = h; -} - -status_t VirtualDisplaySurface::requestBuffer(int pslot, - sp<GraphicBuffer>* outBuf) { - if (mDisplayId < 0) - return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf); - - VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, - "Unexpected requestBuffer pslot=%d in %s state", - pslot, dbgStateStr()); - - *outBuf = mProducerBuffers[pslot]; - return NO_ERROR; -} - -status_t VirtualDisplaySurface::setBufferCount(int bufferCount) { - return mSource[SOURCE_SINK]->setBufferCount(bufferCount); -} - -status_t VirtualDisplaySurface::dequeueBuffer(Source source, - uint32_t format, uint32_t usage, int* sslot, sp<Fence>* fence) { - LOG_FATAL_IF(mDisplayId < 0, "mDisplayId=%d but should not be < 0.", mDisplayId); - // Don't let a slow consumer block us - bool async = (source == SOURCE_SINK); - - status_t result = mSource[source]->dequeueBuffer(sslot, fence, async, - mSinkBufferWidth, mSinkBufferHeight, format, usage); - if (result < 0) - return result; - int pslot = mapSource2ProducerSlot(source, *sslot); - VDS_LOGV("dequeueBuffer(%s): sslot=%d pslot=%d result=%d", - dbgSourceStr(source), *sslot, pslot, result); - uint64_t sourceBit = static_cast<uint64_t>(source) << pslot; - - if ((mProducerSlotSource & (1ULL << pslot)) != sourceBit) { - // This slot was previously dequeued from the other source; must - // re-request the buffer. - result |= BUFFER_NEEDS_REALLOCATION; - mProducerSlotSource &= ~(1ULL << pslot); - mProducerSlotSource |= sourceBit; - } - - if (result & RELEASE_ALL_BUFFERS) { - for (uint32_t i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { - if ((mProducerSlotSource & (1ULL << i)) == sourceBit) - mProducerBuffers[i].clear(); - } - } - if (result & BUFFER_NEEDS_REALLOCATION) { - result = mSource[source]->requestBuffer(*sslot, &mProducerBuffers[pslot]); - if (result < 0) { - mProducerBuffers[pslot].clear(); - mSource[source]->cancelBuffer(*sslot, *fence); - return result; - } - VDS_LOGV("dequeueBuffer(%s): buffers[%d]=%p fmt=%d usage=%#x", - dbgSourceStr(source), pslot, mProducerBuffers[pslot].get(), - mProducerBuffers[pslot]->getPixelFormat(), - mProducerBuffers[pslot]->getUsage()); - } - - return result; -} - -status_t VirtualDisplaySurface::dequeueBuffer(int* pslot, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage) { - if (mDisplayId < 0) - return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, async, w, h, format, usage); - - VDS_LOGW_IF(mDbgState != DBG_STATE_PREPARED, - "Unexpected dequeueBuffer() in %s state", dbgStateStr()); - mDbgState = DBG_STATE_GLES; - - VDS_LOGW_IF(!async, "EGL called dequeueBuffer with !async despite eglSwapInterval(0)"); - VDS_LOGV("dequeueBuffer %dx%d fmt=%d usage=%#x", w, h, format, usage); - - status_t result = NO_ERROR; - Source source = fbSourceForCompositionType(mCompositionType); - - if (source == SOURCE_SINK) { - - if (mOutputProducerSlot < 0) { - // Last chance bailout if something bad happened earlier. For example, - // in a GLES configuration, if the sink disappears then dequeueBuffer - // will fail, the GLES driver won't queue a buffer, but SurfaceFlinger - // will soldier on. So we end up here without a buffer. There should - // be lots of scary messages in the log just before this. - VDS_LOGE("dequeueBuffer: no buffer, bailing out"); - return NO_MEMORY; - } - - // We already dequeued the output buffer. If the GLES driver wants - // something incompatible, we have to cancel and get a new one. This - // will mean that HWC will see a different output buffer between - // prepare and set, but since we're in GLES-only mode already it - // shouldn't matter. - - usage |= GRALLOC_USAGE_HW_COMPOSER; - const sp<GraphicBuffer>& buf = mProducerBuffers[mOutputProducerSlot]; - if ((usage & ~buf->getUsage()) != 0 || - (format != 0 && format != (uint32_t)buf->getPixelFormat()) || - (w != 0 && w != mSinkBufferWidth) || - (h != 0 && h != mSinkBufferHeight)) { - VDS_LOGV("dequeueBuffer: dequeueing new output buffer: " - "want %dx%d fmt=%d use=%#x, " - "have %dx%d fmt=%d use=%#x", - w, h, format, usage, - mSinkBufferWidth, mSinkBufferHeight, - buf->getPixelFormat(), buf->getUsage()); - mOutputFormat = format; - mOutputUsage = usage; - result = refreshOutputBuffer(); - if (result < 0) - return result; - } - } - - if (source == SOURCE_SINK) { - *pslot = mOutputProducerSlot; - *fence = mOutputFence; - } else { - int sslot; - result = dequeueBuffer(source, format, usage, &sslot, fence); - if (result >= 0) { - *pslot = mapSource2ProducerSlot(source, sslot); - } - } - return result; -} - -status_t VirtualDisplaySurface::detachBuffer(int /* slot */) { - VDS_LOGE("detachBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; -} - -status_t VirtualDisplaySurface::detachNextBuffer( - sp<GraphicBuffer>* /* outBuffer */, sp<Fence>* /* outFence */) { - VDS_LOGE("detachNextBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; -} - -status_t VirtualDisplaySurface::attachBuffer(int* /* outSlot */, - const sp<GraphicBuffer>& /* buffer */) { - VDS_LOGE("attachBuffer is not available for VirtualDisplaySurface"); - return INVALID_OPERATION; -} - -status_t VirtualDisplaySurface::queueBuffer(int pslot, - const QueueBufferInput& input, QueueBufferOutput* output) { - if (mDisplayId < 0) - return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output); - - VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, - "Unexpected queueBuffer(pslot=%d) in %s state", pslot, - dbgStateStr()); - mDbgState = DBG_STATE_GLES_DONE; - - VDS_LOGV("queueBuffer pslot=%d", pslot); - - status_t result; - if (mCompositionType == COMPOSITION_MIXED) { - // Queue the buffer back into the scratch pool - QueueBufferOutput scratchQBO; - int sslot = mapProducer2SourceSlot(SOURCE_SCRATCH, pslot); - result = mSource[SOURCE_SCRATCH]->queueBuffer(sslot, input, &scratchQBO); - if (result != NO_ERROR) - return result; - - // Now acquire the buffer from the scratch pool -- should be the same - // slot and fence as we just queued. - Mutex::Autolock lock(mMutex); - BufferQueue::BufferItem item; - result = acquireBufferLocked(&item, 0); - if (result != NO_ERROR) - return result; - VDS_LOGW_IF(item.mBuf != sslot, - "queueBuffer: acquired sslot %d from SCRATCH after queueing sslot %d", - item.mBuf, sslot); - mFbProducerSlot = mapSource2ProducerSlot(SOURCE_SCRATCH, item.mBuf); - mFbFence = mSlots[item.mBuf].mFence; - - } else { - LOG_FATAL_IF(mCompositionType != COMPOSITION_GLES, - "Unexpected queueBuffer in state %s for compositionType %s", - dbgStateStr(), dbgCompositionTypeStr(mCompositionType)); - - // Extract the GLES release fence for HWC to acquire - int64_t timestamp; - bool isAutoTimestamp; - Rect crop; - int scalingMode; - uint32_t transform; - bool async; - input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, - &transform, &async, &mFbFence); - - mFbProducerSlot = pslot; - mOutputFence = mFbFence; - } - - *output = mQueueBufferOutput; - return NO_ERROR; -} - -void VirtualDisplaySurface::cancelBuffer(int pslot, const sp<Fence>& fence) { - if (mDisplayId < 0) - return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence); - - VDS_LOGW_IF(mDbgState != DBG_STATE_GLES, - "Unexpected cancelBuffer(pslot=%d) in %s state", pslot, - dbgStateStr()); - VDS_LOGV("cancelBuffer pslot=%d", pslot); - Source source = fbSourceForCompositionType(mCompositionType); - return mSource[source]->cancelBuffer( - mapProducer2SourceSlot(source, pslot), fence); -} - -int VirtualDisplaySurface::query(int what, int* value) { - switch (what) { - case NATIVE_WINDOW_WIDTH: - *value = mSinkBufferWidth; - break; - case NATIVE_WINDOW_HEIGHT: - *value = mSinkBufferHeight; - break; - default: - return mSource[SOURCE_SINK]->query(what, value); - } - return NO_ERROR; -} - -#if ANDROID_VERSION >= 21 -status_t VirtualDisplaySurface::connect(const sp<IProducerListener>& listener, - int api, bool producerControlledByApp, - QueueBufferOutput* output) { - QueueBufferOutput qbo; - status_t result = mSource[SOURCE_SINK]->connect(listener, api, - producerControlledByApp, &qbo); - if (result == NO_ERROR) { - updateQueueBufferOutput(qbo); - *output = mQueueBufferOutput; - } - return result; -} -#else -status_t VirtualDisplaySurface::connect(const sp<IBinder>& token, - int api, bool producerControlledByApp, - QueueBufferOutput* output) { - QueueBufferOutput qbo; - status_t result = mSource[SOURCE_SINK]->connect(token, api, producerControlledByApp, &qbo); - if (result == NO_ERROR) { - updateQueueBufferOutput(qbo); - *output = mQueueBufferOutput; - } - return result; -} -#endif - -status_t VirtualDisplaySurface::disconnect(int api) { - return mSource[SOURCE_SINK]->disconnect(api); -} - -#if ANDROID_VERSION >= 21 -status_t VirtualDisplaySurface::setSidebandStream(const sp<NativeHandle>& /*stream*/) { - return INVALID_OPERATION; -} -#endif - -void VirtualDisplaySurface::allocateBuffers(bool /* async */, - uint32_t /* width */, uint32_t /* height */, uint32_t /* format */, - uint32_t /* usage */) { - // TODO: Should we actually allocate buffers for a virtual display? -} - -void VirtualDisplaySurface::updateQueueBufferOutput( - const QueueBufferOutput& qbo) { - uint32_t w, h, transformHint, numPendingBuffers; - qbo.deflate(&w, &h, &transformHint, &numPendingBuffers); - mQueueBufferOutput.inflate(w, h, 0, numPendingBuffers); -} - -void VirtualDisplaySurface::resetPerFrameState() { - mCompositionType = COMPOSITION_UNKNOWN; - mFbFence = Fence::NO_FENCE; - mOutputFence = Fence::NO_FENCE; - mOutputProducerSlot = -1; - mFbProducerSlot = -1; -} - -status_t VirtualDisplaySurface::refreshOutputBuffer() { - - return INVALID_OPERATION; - -// XXX Add HWC support - -#if 0 - if (mOutputProducerSlot >= 0) { - mSource[SOURCE_SINK]->cancelBuffer( - mapProducer2SourceSlot(SOURCE_SINK, mOutputProducerSlot), - mOutputFence); - } - - int sslot; - status_t result = dequeueBuffer(SOURCE_SINK, mOutputFormat, mOutputUsage, - &sslot, &mOutputFence); - if (result < 0) - return result; - mOutputProducerSlot = mapSource2ProducerSlot(SOURCE_SINK, sslot); - - // On GLES-only frames, we don't have the right output buffer acquire fence - // until after GLES calls queueBuffer(). So here we just set the buffer - // (for use in HWC prepare) but not the fence; we'll call this again with - // the proper fence once we have it. - result = mHwc.setOutputBuffer(mDisplayId, Fence::NO_FENCE, - mProducerBuffers[mOutputProducerSlot]); - - return result; -#endif -} - -// This slot mapping function is its own inverse, so two copies are unnecessary. -// Both are kept to make the intent clear where the function is called, and for -// the (unlikely) chance that we switch to a different mapping function. -int VirtualDisplaySurface::mapSource2ProducerSlot(Source source, int sslot) { - if (source == SOURCE_SCRATCH) { - return BufferQueue::NUM_BUFFER_SLOTS - sslot - 1; - } else { - return sslot; - } -} -int VirtualDisplaySurface::mapProducer2SourceSlot(Source source, int pslot) { - return mapSource2ProducerSlot(source, pslot); -} - -VirtualDisplaySurface::Source -VirtualDisplaySurface::fbSourceForCompositionType(CompositionType type) { - return type == COMPOSITION_MIXED ? SOURCE_SCRATCH : SOURCE_SINK; -} - -const char* VirtualDisplaySurface::dbgStateStr() const { - switch (mDbgState) { - case DBG_STATE_IDLE: return "IDLE"; - case DBG_STATE_PREPARED: return "PREPARED"; - case DBG_STATE_GLES: return "GLES"; - case DBG_STATE_GLES_DONE: return "GLES_DONE"; - case DBG_STATE_HWC: return "HWC"; - default: return "INVALID"; - } -} - -const char* VirtualDisplaySurface::dbgSourceStr(Source s) { - switch (s) { - case SOURCE_SINK: return "SINK"; - case SOURCE_SCRATCH: return "SCRATCH"; - default: return "INVALID"; - } -} - -// --------------------------------------------------------------------------- -} // namespace android -// --------------------------------------------------------------------------- diff --git a/widget/gonk/libdisplay/VirtualDisplaySurface.h b/widget/gonk/libdisplay/VirtualDisplaySurface.h deleted file mode 100644 index 9125d8751..000000000 --- a/widget/gonk/libdisplay/VirtualDisplaySurface.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2013 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_VIRTUAL_DISPLAY_SURFACE_H -#define ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H - -#include <gui/IGraphicBufferProducer.h> - -#include "DisplaySurface.h" - -// --------------------------------------------------------------------------- -namespace android { -// --------------------------------------------------------------------------- - -class HWComposer; -class IProducerListener; - -/* This DisplaySurface implementation supports virtual displays, where GLES - * and/or HWC compose into a buffer that is then passed to an arbitrary - * consumer (the sink) running in another process. - * - * The simplest case is when the virtual display will never use the h/w - * composer -- either the h/w composer doesn't support writing to buffers, or - * there are more virtual displays than it supports simultaneously. In this - * case, the GLES driver works directly with the output buffer queue, and - * calls to the VirtualDisplay from SurfaceFlinger and DisplayHardware do - * nothing. - * - * If h/w composer might be used, then each frame will fall into one of three - * configurations: GLES-only, HWC-only, and MIXED composition. In all of these, - * we must provide a FB target buffer and output buffer for the HWC set() call. - * - * In GLES-only composition, the GLES driver is given a buffer from the sink to - * render into. When the GLES driver queues the buffer to the - * VirtualDisplaySurface, the VirtualDisplaySurface holds onto it instead of - * immediately queueing it to the sink. The buffer is used as both the FB - * target and output buffer for HWC, though on these frames the HWC doesn't - * do any work for this display and doesn't write to the output buffer. After - * composition is complete, the buffer is queued to the sink. - * - * In HWC-only composition, the VirtualDisplaySurface dequeues a buffer from - * the sink and passes it to HWC as both the FB target buffer and output - * buffer. The HWC doesn't need to read from the FB target buffer, but does - * write to the output buffer. After composition is complete, the buffer is - * queued to the sink. - * - * On MIXED frames, things become more complicated, since some h/w composer - * implementations can't read from and write to the same buffer. This class has - * an internal BufferQueue that it uses as a scratch buffer pool. The GLES - * driver is given a scratch buffer to render into. When it finishes rendering, - * the buffer is queued and then immediately acquired by the - * VirtualDisplaySurface. The scratch buffer is then used as the FB target - * buffer for HWC, and a separate buffer is dequeued from the sink and used as - * the HWC output buffer. When HWC composition is complete, the scratch buffer - * is released and the output buffer is queued to the sink. - */ -class VirtualDisplaySurface : public DisplaySurface, - public BnGraphicBufferProducer { -public: - VirtualDisplaySurface(int32_t dispId, - const sp<IGraphicBufferProducer>& sink, - const sp<IGraphicBufferProducer>& bqProducer, - const sp<StreamConsumer>& bqConsumer, - const String8& name); - - // - // DisplaySurface interface - // - virtual status_t beginFrame(bool mustRecompose); - virtual status_t prepareFrame(CompositionType compositionType); - virtual status_t compositionComplete(); - virtual status_t advanceFrame(); - virtual void onFrameCommitted(); - virtual void resizeBuffers(const uint32_t w, const uint32_t h); - - virtual status_t setReleaseFenceFd(int fenceFd) { return INVALID_OPERATION; } - virtual int GetPrevDispAcquireFd() { return -1; }; - -private: - enum Source {SOURCE_SINK = 0, SOURCE_SCRATCH = 1}; - - virtual ~VirtualDisplaySurface(); - - // - // IGraphicBufferProducer interface, used by the GLES driver. - // - virtual status_t requestBuffer(int pslot, sp<GraphicBuffer>* outBuf); - virtual status_t setBufferCount(int bufferCount); - virtual status_t dequeueBuffer(int* pslot, sp<Fence>* fence, bool async, - uint32_t w, uint32_t h, uint32_t format, uint32_t usage); - virtual status_t detachBuffer(int slot); - virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, - sp<Fence>* outFence); - virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer); - virtual status_t queueBuffer(int pslot, - const QueueBufferInput& input, QueueBufferOutput* output); - virtual void cancelBuffer(int pslot, const sp<Fence>& fence); - virtual int query(int what, int* value); -#if ANDROID_VERSION >= 21 - virtual status_t connect(const sp<IProducerListener>& listener, - int api, bool producerControlledByApp, QueueBufferOutput* output); -#else - virtual status_t connect(const sp<IBinder>& token, - int api, bool producerControlledByApp, QueueBufferOutput* output); -#endif - virtual status_t disconnect(int api); -#if ANDROID_VERSION >= 21 - virtual status_t setSidebandStream(const sp<NativeHandle>& stream); -#endif - virtual void allocateBuffers(bool async, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage); - - // - // Utility methods - // - static Source fbSourceForCompositionType(CompositionType type); - status_t dequeueBuffer(Source source, uint32_t format, uint32_t usage, - int* sslot, sp<Fence>* fence); - void updateQueueBufferOutput(const QueueBufferOutput& qbo); - void resetPerFrameState(); - status_t refreshOutputBuffer(); - - // Both the sink and scratch buffer pools have their own set of slots - // ("source slots", or "sslot"). We have to merge these into the single - // set of slots used by the GLES producer ("producer slots" or "pslot") and - // internally in the VirtualDisplaySurface. To minimize the number of times - // a producer slot switches which source it comes from, we map source slot - // numbers to producer slot numbers differently for each source. - static int mapSource2ProducerSlot(Source source, int sslot); - static int mapProducer2SourceSlot(Source source, int pslot); - - // - // Immutable after construction - // - const int32_t mDisplayId; - const String8 mDisplayName; - sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_* - uint32_t mDefaultOutputFormat; - - // - // Inter-frame state - // - - // To avoid buffer reallocations, we track the buffer usage and format - // we used on the previous frame and use it again on the new frame. If - // the composition type changes or the GLES driver starts requesting - // different usage/format, we'll get a new buffer. - uint32_t mOutputFormat; - uint32_t mOutputUsage; - - // Since we present a single producer interface to the GLES driver, but - // are internally muxing between the sink and scratch producers, we have - // to keep track of which source last returned each producer slot from - // dequeueBuffer. Each bit in mProducerSlotSource corresponds to a producer - // slot. Both mProducerSlotSource and mProducerBuffers are indexed by a - // "producer slot"; see the mapSlot*() functions. - uint64_t mProducerSlotSource; - sp<GraphicBuffer> mProducerBuffers[BufferQueue::NUM_BUFFER_SLOTS]; - - // The QueueBufferOutput with the latest info from the sink, and with the - // transform hint cleared. Since we defer queueBuffer from the GLES driver - // to the sink, we have to return the previous version. - QueueBufferOutput mQueueBufferOutput; - - // Details of the current sink buffer. These become valid when a buffer is - // dequeued from the sink, and are used when queueing the buffer. - uint32_t mSinkBufferWidth, mSinkBufferHeight; - - // - // Intra-frame state - // - - // Composition type and GLES buffer source for the current frame. - // Valid after prepareFrame(), cleared in onFrameCommitted. - CompositionType mCompositionType; - - // mFbFence is the fence HWC should wait for before reading the framebuffer - // target buffer. - sp<Fence> mFbFence; - - // mOutputFence is the fence HWC should wait for before writing to the - // output buffer. - sp<Fence> mOutputFence; - - // Producer slot numbers for the buffers to use for HWC framebuffer target - // and output. - int mFbProducerSlot; - int mOutputProducerSlot; - - // Debug only -- track the sequence of events in each frame so we can make - // sure they happen in the order we expect. This class implicitly models - // a state machine; this enum/variable makes it explicit. - // - // +-----------+-------------------+-------------+ - // | State | Event || Next State | - // +-----------+-------------------+-------------+ - // | IDLE | beginFrame || BEGUN | - // | BEGUN | prepareFrame || PREPARED | - // | PREPARED | dequeueBuffer [1] || GLES | - // | PREPARED | advanceFrame [2] || HWC | - // | GLES | queueBuffer || GLES_DONE | - // | GLES_DONE | advanceFrame || HWC | - // | HWC | onFrameCommitted || IDLE | - // +-----------+-------------------++------------+ - // [1] COMPOSITION_GLES and COMPOSITION_MIXED frames. - // [2] COMPOSITION_HWC frames. - // - enum DbgState { - // no buffer dequeued, don't know anything about the next frame - DBG_STATE_IDLE, - // output buffer dequeued, framebuffer source not yet known - DBG_STATE_BEGUN, - // output buffer dequeued, framebuffer source known but not provided - // to GLES yet. - DBG_STATE_PREPARED, - // GLES driver has a buffer dequeued - DBG_STATE_GLES, - // GLES driver has queued the buffer, we haven't sent it to HWC yet - DBG_STATE_GLES_DONE, - // HWC has the buffer for this frame - DBG_STATE_HWC, - }; - DbgState mDbgState; - CompositionType mDbgLastCompositionType; - - const char* dbgStateStr() const; - static const char* dbgSourceStr(Source s); - - bool mMustRecompose; -}; - -// --------------------------------------------------------------------------- -} // namespace android -// --------------------------------------------------------------------------- - -#endif // ANDROID_SF_VIRTUAL_DISPLAY_SURFACE_H - diff --git a/widget/gonk/libdisplay/moz.build b/widget/gonk/libdisplay/moz.build deleted file mode 100644 index 917320592..000000000 --- a/widget/gonk/libdisplay/moz.build +++ /dev/null @@ -1,59 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# Copyright 2013 Mozilla Foundation and Mozilla contributors -# -# 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. - -SOURCES += [ - 'BootAnimation.cpp', -] - -if CONFIG['ANDROID_VERSION'] >= '19': - SOURCES += [ - 'FramebufferSurface.cpp', - 'GonkDisplayJB.cpp', - 'VirtualDisplaySurface.cpp', - ] -elif CONFIG['ANDROID_VERSION'] == '18': - SOURCES += [ - 'FramebufferSurface.cpp', - 'GonkDisplayJB.cpp', - ] -elif CONFIG['ANDROID_VERSION'] == '17': - SOURCES += [ - 'FramebufferSurface.cpp', - 'GonkDisplayJB.cpp', - 'GraphicBufferAlloc.cpp', - ] -elif CONFIG['ANDROID_VERSION'] and CONFIG['COMPILE_ENVIRONMENT']: - error('Unsupported platform version: %s' % (CONFIG['ANDROID_VERSION'])) - -Library('display') - -include('/ipc/chromium/chromium-config.mozbuild') - -FORCE_STATIC_LIB = True - -DEFINES['XPCOM_GLUE'] = True - -DISABLE_STL_WRAPPING = True - -LOCAL_INCLUDES += [ - '%' + '%s/%s' % (CONFIG['ANDROID_SOURCE'], d) for d in [ - 'frameworks/native/include/gui', - 'frameworks/native/opengl/include', - 'hardware/libhardware/include', - 'hardware/libhardware_legacy/include', - 'system/core/libsuspend/include', - ] -] |