| The Android Open Source Project | 7c1b96a | 2008-10-21 07:00:00 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2007 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 LOG_TAG "SurfaceFlinger" | 
 | 18 |  | 
 | 19 | #include <stdlib.h> | 
 | 20 | #include <stdint.h> | 
 | 21 | #include <sys/types.h> | 
 | 22 |  | 
 | 23 | #include <utils/Errors.h> | 
 | 24 | #include <utils/Log.h> | 
 | 25 |  | 
| The Android Open Source Project | 2762932 | 2009-01-09 17:51:23 -0800 | [diff] [blame] | 26 | #include <core/SkBitmap.h> | 
| The Android Open Source Project | 7c1b96a | 2008-10-21 07:00:00 -0700 | [diff] [blame] | 27 |  | 
 | 28 | #include <ui/EGLDisplaySurface.h> | 
 | 29 |  | 
 | 30 | #include "LayerBase.h" | 
 | 31 | #include "LayerScreenshot.h" | 
 | 32 | #include "SurfaceFlinger.h" | 
 | 33 | #include "DisplayHardware/DisplayHardware.h" | 
 | 34 |  | 
 | 35 | namespace android { | 
 | 36 | // --------------------------------------------------------------------------- | 
 | 37 |  | 
 | 38 | const uint32_t LayerScreenshot::typeInfo = LayerBase::typeInfo | 0x20; | 
 | 39 | const char* const LayerScreenshot::typeID = "LayerScreenshot"; | 
 | 40 |  | 
 | 41 | // --------------------------------------------------------------------------- | 
 | 42 |  | 
 | 43 | LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display) | 
 | 44 |     : LayerBase(flinger, display), mReply(0) | 
 | 45 | { | 
 | 46 | } | 
 | 47 |  | 
 | 48 | LayerScreenshot::~LayerScreenshot() | 
 | 49 | { | 
 | 50 | } | 
 | 51 |  | 
 | 52 | void LayerScreenshot::onDraw(const Region& clip) const | 
 | 53 | { | 
 | 54 |     const DisplayHardware& hw(graphicPlane(0).displayHardware()); | 
 | 55 |     copybit_image_t dst; | 
 | 56 |     hw.getDisplaySurface(&dst); | 
 | 57 |     if (dst.base != 0) { | 
 | 58 |         uint8_t const* src = (uint8_t const*)(intptr_t(dst.base) + dst.offset);  | 
 | 59 |         const int fbWidth = dst.w; | 
 | 60 |         const int fbHeight = dst.h; | 
 | 61 |         const int fbFormat = dst.format; | 
 | 62 |  | 
 | 63 |         int x = mTransformedBounds.left; | 
 | 64 |         int y = mTransformedBounds.top; | 
 | 65 |         int w = mTransformedBounds.width(); | 
 | 66 |         int h = mTransformedBounds.height(); | 
 | 67 |         Parcel* const reply = mReply; | 
 | 68 |         if (reply) { | 
 | 69 |             const size_t Bpp = bytesPerPixel(fbFormat); | 
 | 70 |             const size_t size = w * h * Bpp; | 
 | 71 |             int32_t cfg = SkBitmap::kNo_Config; | 
 | 72 |             switch (fbFormat) { | 
| Adrian Taylor | f18936cb | 2009-02-11 15:06:19 +0000 | [diff] [blame] | 73 |                 case PIXEL_FORMAT_RGBA_4444: cfg = SkBitmap::kARGB_4444_Config; break; | 
 | 74 |                 case PIXEL_FORMAT_RGBA_8888: cfg = SkBitmap::kARGB_8888_Config; break; | 
 | 75 |                 case PIXEL_FORMAT_RGB_565:   cfg = SkBitmap::kRGB_565_Config; break; | 
 | 76 |                 case PIXEL_FORMAT_A_8:       cfg = SkBitmap::kA8_Config; break; | 
| The Android Open Source Project | 7c1b96a | 2008-10-21 07:00:00 -0700 | [diff] [blame] | 77 |             } | 
 | 78 |             reply->writeInt32(0); | 
 | 79 |             reply->writeInt32(cfg); | 
 | 80 |             reply->writeInt32(w); | 
 | 81 |             reply->writeInt32(h); | 
 | 82 |             reply->writeInt32(w * Bpp); | 
 | 83 |             void* data = reply->writeInplace(size); | 
 | 84 |             if (data) { | 
 | 85 |                 uint8_t* d = (uint8_t*)data; | 
 | 86 |                 uint8_t const* s = src + (x + y*fbWidth) * Bpp; | 
 | 87 |                 if (w == fbWidth) { | 
 | 88 |                     memcpy(d, s, w*h*Bpp);    | 
 | 89 |                 } else { | 
 | 90 |                     for (int y=0 ; y<h ; y++) { | 
 | 91 |                         memcpy(d, s, w*Bpp); | 
 | 92 |                         d += w*Bpp; | 
 | 93 |                         s += fbWidth*Bpp; | 
 | 94 |                     } | 
 | 95 |                 } | 
 | 96 |             } | 
 | 97 |         } | 
 | 98 |     } | 
 | 99 |     mCV.broadcast(); | 
 | 100 | } | 
 | 101 |  | 
 | 102 | void LayerScreenshot::takeScreenshot(Mutex& lock, Parcel* reply) | 
 | 103 | { | 
 | 104 |     mReply = reply; | 
 | 105 |     mCV.wait(lock); | 
 | 106 | } | 
 | 107 |  | 
 | 108 | // --------------------------------------------------------------------------- | 
 | 109 |  | 
 | 110 | }; // namespace android |