blob: fb7b585146853da2ab2b5e172b986247eb49b8a8 [file] [log] [blame]
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -07001/*
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 Projectb7986892009-01-09 17:51:23 -080026#include <core/SkBitmap.h>
The Android Open Source Project54b6cfa2008-10-21 07:00:00 -070027
28#include <ui/EGLDisplaySurface.h>
29
30#include "LayerBase.h"
31#include "LayerScreenshot.h"
32#include "SurfaceFlinger.h"
33#include "DisplayHardware/DisplayHardware.h"
34
35namespace android {
36// ---------------------------------------------------------------------------
37
38const uint32_t LayerScreenshot::typeInfo = LayerBase::typeInfo | 0x20;
39const char* const LayerScreenshot::typeID = "LayerScreenshot";
40
41// ---------------------------------------------------------------------------
42
43LayerScreenshot::LayerScreenshot(SurfaceFlinger* flinger, DisplayID display)
44 : LayerBase(flinger, display), mReply(0)
45{
46}
47
48LayerScreenshot::~LayerScreenshot()
49{
50}
51
52void 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 Taylorefd826e2009-02-11 15:06:19 +000073 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 Project54b6cfa2008-10-21 07:00:00 -070077 }
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
102void LayerScreenshot::takeScreenshot(Mutex& lock, Parcel* reply)
103{
104 mReply = reply;
105 mCV.wait(lock);
106}
107
108// ---------------------------------------------------------------------------
109
110}; // namespace android