Bug 1155797 - Part 2: Show a black solid color frame if we don't have the bootAnim. r=mwu, a=jocheng
authorJerryShih <hshih@mozilla.com>
Sun, 17 May 2015 18:11:00 +0200
changeset 238444 31a8e155e4906ae05957b36ea54acdbbc5e0c970
parent 238443 c7182dcaee4277f0ae0ce30a2863c16cc38c865e
child 238445 9f090b47fed8b579e2e2b606522e35796b25b2ad
push id624
push userryanvm@gmail.com
push dateThu, 21 May 2015 01:28:21 +0000
treeherdermozilla-b2g37_v2_2@6e4eaf59efda [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmwu, jocheng
bugs1155797
milestone37.0
Bug 1155797 - Part 2: Show a black solid color frame if we don't have the bootAnim. r=mwu, a=jocheng
widget/gonk/libdisplay/BootAnimation.cpp
--- a/widget/gonk/libdisplay/BootAnimation.cpp
+++ b/widget/gonk/libdisplay/BootAnimation.cpp
@@ -465,58 +465,89 @@ AsBackgroundFill(const png_color_16& col
         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;
     }
 
-    GonkDisplay *display = GetGonkDisplay();
-    int format = display->surfaceformat;
-
-    hw_module_t const *module;
-    if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module)) {
-        LOGW("Could not get gralloc module");
-        return nullptr;
-    }
-    gralloc_module_t const *grmodule =
-        reinterpret_cast<gralloc_module_t const*>(module);
-
     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.
      *
@@ -637,27 +668,32 @@ AnimationThread(void *)
 
                 if (tv2.tv_usec < frameDelayUs) {
                     usleep(frameDelayUs - tv2.tv_usec);
                 } else {
                     LOGW("Frame delay is %d us but decoding took %d 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;
 }
 
 void
 StartBootAnimation()
 {
     sRunAnimation = true;
     pthread_create(&sAnimationThread, nullptr, AnimationThread, nullptr);