Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: experimental/flocking_geese/nacl_app/sprite.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "nacl_app/sprite.h"
6
7 #include <algorithm>
8
9 namespace {
10 const uint32_t kRedBlueMask = 0x00FF00FF;
11 const uint32_t kGreenMask = 0x0000FF00;
12 const uint32_t kAlphaMask = 0xFF000000;
13 const uint32_t k8x2Scale = 0x800080;
14 const uint32_t kPixelOne = 0xFF;
15 const uint32_t kAlphaShift = 24;
16
17 // Use Blinn & Smith's method of scaling by 256, instead of 255. Blends two
18 // colour channels simultaneously: the R and B of an ARGB pixel.
19 // This code expects rb as a packed 16:16 fixed point number, and a as an 8-bit
20 // value in [0..255].
21 inline uint32_t Blend8x2(uint32_t rb, uint32_t a) {
22 rb &= kRedBlueMask;
23 uint32_t blend = a * rb + k8x2Scale; // Scale by 256.
24 return (blend + ((blend >> 8) & kRedBlueMask)) >> 8 & kRedBlueMask;
25 }
26
27 } // namespace
28
29 namespace flocking_geese {
30
31 Sprite::Sprite(uint32_t* pixel_buffer,
32 const pp::Size& size,
33 int32_t row_bytes) {
34 SetPixelBuffer(pixel_buffer, size, row_bytes);
35 }
36
37 void Sprite::SetPixelBuffer(uint32_t* pixel_buffer,
38 const pp::Size& size,
39 int32_t row_bytes) {
40 pixel_buffer_.reset(pixel_buffer);
41 pixel_buffer_size_ = size;
42 row_bytes_ = row_bytes ? row_bytes : size.width() * sizeof(uint32_t);
43 }
44
45 void Sprite::CompositeFromRectToPoint(const pp::Rect& src_rect,
46 uint32_t* dest_pixel_buffer,
47 const pp::Rect& dest_bounds,
48 int32_t dest_row_bytes,
49 const pp::Point& dest_point) const {
50 // Clip the source rect to the source image bounds.
51 pp::Rect src_bounds(pp::Point(), size());
52 pp::Rect src_rect_clipped(src_rect.Intersect(src_bounds));
53 if (src_rect_clipped.IsEmpty())
54 return;
55
56 // Create a clipped rect in the destination coordinate space that contains the
57 // final image.
58 pp::Rect draw_rect(dest_point, src_rect_clipped.size());
59 pp::Rect draw_rect_clipped(dest_bounds.Intersect(draw_rect));
60 if (draw_rect_clipped.IsEmpty())
61 return;
62 // Transform the destination rectangle back to the source image coordinate
63 // system: Translate(-dest_point) . Translate(src_rect_clipped.origin).
64 pp::Point src_offset(draw_rect_clipped.point());
65 src_offset -= dest_point;
66 src_rect_clipped.Offset(src_offset);
67 src_rect_clipped.set_size(draw_rect_clipped.size());
68 size_t src_byte_offset = src_rect_clipped.x() * sizeof(uint32_t) +
69 src_rect_clipped.y() * row_bytes_;
70 const uint8_t* src_pixels =
71 reinterpret_cast<const uint8_t*>(pixel_buffer_.get()) + src_byte_offset;
72
73 if (dest_row_bytes == 0)
74 dest_row_bytes = dest_bounds.width() * sizeof(uint32_t);
75 size_t dest_byte_offset = draw_rect_clipped.point().x() * sizeof(uint32_t) +
76 draw_rect_clipped.point().y() * dest_row_bytes;
77 uint8_t* dest_pixels = reinterpret_cast<uint8_t*>(dest_pixel_buffer) +
78 dest_byte_offset;
79
80 // All the pointers are set up, now do the SOver. Note that the only pre-
81 // multiplied alpha formats are supported.
82 for (int32_t y = 0; y < src_rect_clipped.height(); ++y) {
83 const uint32_t* src_scanline =
84 reinterpret_cast<const uint32_t*>(src_pixels);
85 uint32_t* dest_scanline = reinterpret_cast<uint32_t*>(dest_pixels);
86 for (int32_t x = 0; x < src_rect_clipped.width(); ++x) {
87 uint32_t src = *src_scanline++;
88 uint32_t dst = *dest_scanline;
89 uint32_t alpha = (src >> kAlphaShift) & kPixelOne;
90 uint32_t one_minus_alpha = kPixelOne - alpha;
91 // Compute RB and G separately: this allows for SIMD-like behaviour
92 // when multiplying the channels by alpha. Note that over-saturated
93 // pixels will wrap to 0 and not clamp.
94 uint32_t dst_rb = Blend8x2(dst, one_minus_alpha);
95 uint32_t dst_ga = Blend8x2(dst >> 8, one_minus_alpha) << 8;
96 *dest_scanline++ = src + dst_rb + dst_ga;
97 }
98 src_pixels += row_bytes_;
99 dest_pixels += dest_row_bytes;
100 }
101 }
102
103 } // namespace flocking_geese
104
OLDNEW
« no previous file with comments | « experimental/flocking_geese/nacl_app/sprite.h ('k') | experimental/flocking_geese/nacl_app/vector2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698