Home | History | Annotate | Download | only in common
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "tests/common/TestContext.h"
     18 
     19 #include <cutils/trace.h>
     20 
     21 namespace android {
     22 namespace uirenderer {
     23 namespace test {
     24 
     25 static const int IDENT_DISPLAYEVENT = 1;
     26 
     27 static android::DisplayInfo DUMMY_DISPLAY{
     28         1080,   // w
     29         1920,   // h
     30         320.0,  // xdpi
     31         320.0,  // ydpi
     32         60.0,   // fps
     33         2.0,    // density
     34         0,      // orientation
     35         false,  // secure?
     36         0,      // appVsyncOffset
     37         0,      // presentationDeadline
     38 };
     39 
     40 DisplayInfo getInternalDisplay() {
     41 #if !HWUI_NULL_GPU
     42     DisplayInfo display;
     43     const sp<IBinder> token = SurfaceComposerClient::getInternalDisplayToken();
     44     LOG_ALWAYS_FATAL_IF(token == nullptr,
     45                         "Failed to get display info because internal display is disconnected\n");
     46     status_t status = SurfaceComposerClient::getDisplayInfo(token, &display);
     47     LOG_ALWAYS_FATAL_IF(status, "Failed to get display info\n");
     48     return display;
     49 #else
     50     return DUMMY_DISPLAY;
     51 #endif
     52 }
     53 
     54 // Initialize to a dummy default
     55 android::DisplayInfo gDisplay = DUMMY_DISPLAY;
     56 
     57 TestContext::TestContext() {
     58     mLooper = new Looper(true);
     59     mSurfaceComposerClient = new SurfaceComposerClient();
     60     mLooper->addFd(mDisplayEventReceiver.getFd(), IDENT_DISPLAYEVENT, Looper::EVENT_INPUT, nullptr,
     61                    nullptr);
     62 }
     63 
     64 TestContext::~TestContext() {}
     65 
     66 sp<Surface> TestContext::surface() {
     67     if (!mSurface.get()) {
     68         createSurface();
     69     }
     70     return mSurface;
     71 }
     72 
     73 void TestContext::createSurface() {
     74     if (mRenderOffscreen) {
     75         createOffscreenSurface();
     76     } else {
     77         createWindowSurface();
     78     }
     79 }
     80 
     81 void TestContext::createWindowSurface() {
     82     mSurfaceControl = mSurfaceComposerClient->createSurface(String8("HwuiTest"), gDisplay.w,
     83                                                             gDisplay.h, PIXEL_FORMAT_RGBX_8888);
     84 
     85     SurfaceComposerClient::Transaction t;
     86     t.setLayer(mSurfaceControl, 0x7FFFFFF).show(mSurfaceControl).apply();
     87     mSurface = mSurfaceControl->getSurface();
     88 }
     89 
     90 void TestContext::createOffscreenSurface() {
     91     sp<IGraphicBufferProducer> producer;
     92     sp<IGraphicBufferConsumer> consumer;
     93     BufferQueue::createBufferQueue(&producer, &consumer);
     94     producer->setMaxDequeuedBufferCount(3);
     95     producer->setAsyncMode(true);
     96     mConsumer = new BufferItemConsumer(consumer, GRALLOC_USAGE_HW_COMPOSER, 4);
     97     mConsumer->setDefaultBufferSize(gDisplay.w, gDisplay.h);
     98     mSurface = new Surface(producer);
     99 }
    100 
    101 void TestContext::waitForVsync() {
    102     // Hacky fix for not getting sysprop change callbacks
    103     // We just poll the sysprop in vsync since it's when the UI thread is
    104     // "idle" and shouldn't burn too much time
    105     atrace_update_tags();
    106 
    107     if (mConsumer.get()) {
    108         BufferItem buffer;
    109         if (mConsumer->acquireBuffer(&buffer, 0, false) == OK) {
    110             // We assume the producer is internally ordered enough such that
    111             // it is unneccessary to set a release fence
    112             mConsumer->releaseBuffer(buffer);
    113         }
    114         // We running free, go go go!
    115         return;
    116     }
    117 #if !HWUI_NULL_GPU
    118     // Request vsync
    119     mDisplayEventReceiver.requestNextVsync();
    120 
    121     // Wait
    122     mLooper->pollOnce(-1);
    123 
    124     // Drain it
    125     DisplayEventReceiver::Event buf[100];
    126     while (mDisplayEventReceiver.getEvents(buf, 100) > 0) {
    127     }
    128 #endif
    129 }
    130 
    131 }  // namespace test
    132 }  // namespace uirenderer
    133 }  // namespace android
    134