1 /* 2 * Copyright 2019 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 #define ATRACE_TAG ATRACE_TAG_GRAPHICS 18 #define LOG_TAG "SamplingTest" 19 20 #include <chrono> 21 #include <thread> 22 23 #include <binder/IPCThreadState.h> 24 #include <binder/ProcessState.h> 25 #include <gui/IRegionSamplingListener.h> 26 #include <gui/ISurfaceComposer.h> 27 #include <gui/SurfaceComposerClient.h> 28 #include <gui/SurfaceControl.h> 29 #include <private/gui/ComposerService.h> 30 #include <utils/Trace.h> 31 32 using namespace std::chrono_literals; 33 34 namespace android { 35 36 class Button : public BnRegionSamplingListener { 37 public: 38 Button(const char* name, const Rect& samplingArea) { 39 sp<SurfaceComposerClient> client = new SurfaceComposerClient; 40 41 mButton = client->createSurface(String8(name), 0, 0, PIXEL_FORMAT_RGBA_8888, 42 ISurfaceComposerClient::eFXSurfaceColor); 43 44 const int32_t width = samplingArea.getWidth(); 45 const int32_t height = samplingArea.getHeight(); 46 47 SurfaceComposerClient::Transaction{} 48 .setLayer(mButton, 0x7fffffff) 49 .setCrop_legacy(mButton, 50 {0, 0, width - 2 * BUTTON_PADDING, height - 2 * BUTTON_PADDING}) 51 .setPosition(mButton, samplingArea.left + BUTTON_PADDING, 52 samplingArea.top + BUTTON_PADDING) 53 .setColor(mButton, half3{1, 1, 1}) 54 .show(mButton) 55 .apply(); 56 57 mButtonBlend = client->createSurface(String8(name) + "Blend", 0, 0, PIXEL_FORMAT_RGBA_8888, 58 ISurfaceComposerClient::eFXSurfaceColor); 59 60 SurfaceComposerClient::Transaction{} 61 .setLayer(mButtonBlend, 0x7ffffffe) 62 .setCrop_legacy(mButtonBlend, 63 {0, 0, width - 2 * SAMPLE_AREA_PADDING, 64 height - 2 * SAMPLE_AREA_PADDING}) 65 .setPosition(mButtonBlend, samplingArea.left + SAMPLE_AREA_PADDING, 66 samplingArea.top + SAMPLE_AREA_PADDING) 67 .setColor(mButtonBlend, half3{1, 1, 1}) 68 .setAlpha(mButtonBlend, 0.2) 69 .show(mButtonBlend) 70 .apply(true); 71 72 const bool HIGHLIGHT_SAMPLING_AREA = false; 73 if (HIGHLIGHT_SAMPLING_AREA) { 74 mSamplingArea = 75 client->createSurface(String8("SamplingArea"), 0, 0, PIXEL_FORMAT_RGBA_8888, 76 ISurfaceComposerClient::eFXSurfaceColor); 77 78 SurfaceComposerClient::Transaction{} 79 .setLayer(mSamplingArea, 0x7ffffffd) 80 .setCrop_legacy(mSamplingArea, {0, 0, 100, 32}) 81 .setPosition(mSamplingArea, 490, 1606) 82 .setColor(mSamplingArea, half3{0, 1, 0}) 83 .setAlpha(mSamplingArea, 0.1) 84 .show(mSamplingArea) 85 .apply(); 86 } 87 } 88 89 sp<IBinder> getStopLayerHandle() { return mButtonBlend->getHandle(); } 90 91 private: 92 static const int32_t BLEND_WIDTH = 2; 93 static const int32_t SAMPLE_AREA_PADDING = 8; 94 static const int32_t BUTTON_PADDING = BLEND_WIDTH + SAMPLE_AREA_PADDING; 95 96 void setColor(float color) { 97 const float complement = std::fmod(color + 0.5f, 1.0f); 98 SurfaceComposerClient::Transaction{} 99 .setColor(mButton, half3{complement, complement, complement}) 100 .setColor(mButtonBlend, half3{color, color, color}) 101 .apply(); 102 } 103 104 void onSampleCollected(float medianLuma) override { 105 ATRACE_CALL(); 106 setColor(medianLuma); 107 } 108 109 sp<SurfaceComposerClient> mClient; 110 sp<SurfaceControl> mButton; 111 sp<SurfaceControl> mButtonBlend; 112 sp<SurfaceControl> mSamplingArea; 113 }; 114 115 } // namespace android 116 117 using namespace android; 118 119 int main(int, const char**) { 120 const Rect homeButtonArea{490, 1606, 590, 1654}; 121 sp<android::Button> homeButton = new android::Button("HomeButton", homeButtonArea); 122 const Rect backButtonArea{200, 1606, 248, 1654}; 123 sp<android::Button> backButton = new android::Button("BackButton", backButtonArea); 124 125 sp<ISurfaceComposer> composer = ComposerService::getComposerService(); 126 composer->addRegionSamplingListener(homeButtonArea, homeButton->getStopLayerHandle(), 127 homeButton); 128 composer->addRegionSamplingListener(backButtonArea, backButton->getStopLayerHandle(), 129 backButton); 130 131 ProcessState::self()->startThreadPool(); 132 IPCThreadState::self()->joinThreadPool(); 133 134 return 0; 135 } 136