This is an automated email from the git hooks/post-receive script. thansen pushed a commit to branch master in repository aseprite.
commit 9e6d7632d9432117005c954a1818429295bf7c2c Author: David Capello <davidcape...@gmail.com> Date: Wed Jun 29 10:01:14 2016 -0300 Minor Render improvement We can return the specific function to composite images depending on the actual zoom level. In this commit I include a new composite_image_without_scale() to completely ignore the zoom level when it's possible. --- src/render/render.cpp | 307 ++++++++++++++++++++++++++++++-------------------- src/render/render.h | 45 ++++---- 2 files changed, 211 insertions(+), 141 deletions(-) diff --git a/src/render/render.cpp b/src/render/render.cpp index 3e0ad35..0b98198 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -21,17 +21,19 @@ namespace render { +namespace { + ////////////////////////////////////////////////////////////////////// // Scaled composite template<class DstTraits, class SrcTraits> class BlenderHelper { - BlendFunc m_blend_func; + BlendFunc m_blendFunc; color_t m_mask_color; public: - BlenderHelper(const Image* src, const Palette* pal, BlendMode blend_mode) + BlenderHelper(const Image* src, const Palette* pal, BlendMode blendMode) { - m_blend_func = SrcTraits::get_blender(blend_mode); + m_blendFunc = SrcTraits::get_blender(blendMode); m_mask_color = src->maskColor(); } inline typename DstTraits::pixel_t @@ -40,7 +42,7 @@ public: int opacity) { if (src != m_mask_color) - return (*m_blend_func)(dst, src, opacity); + return (*m_blendFunc)(dst, src, opacity); else return dst; } @@ -48,12 +50,12 @@ public: template<> class BlenderHelper<RgbTraits, GrayscaleTraits> { - BlendFunc m_blend_func; + BlendFunc m_blendFunc; color_t m_mask_color; public: - BlenderHelper(const Image* src, const Palette* pal, BlendMode blend_mode) + BlenderHelper(const Image* src, const Palette* pal, BlendMode blendMode) { - m_blend_func = RgbTraits::get_blender(blend_mode); + m_blendFunc = RgbTraits::get_blender(blendMode); m_mask_color = src->maskColor(); } inline RgbTraits::pixel_t @@ -63,7 +65,7 @@ public: { if (src != m_mask_color) { int v = graya_getv(src); - return (*m_blend_func)(dst, rgba(v, v, v, graya_geta(src)), opacity); + return (*m_blendFunc)(dst, rgba(v, v, v, graya_geta(src)), opacity); } else return dst; @@ -73,14 +75,14 @@ public: template<> class BlenderHelper<RgbTraits, IndexedTraits> { const Palette* m_pal; - BlendMode m_blend_mode; - BlendFunc m_blend_func; + BlendMode m_blendMode; + BlendFunc m_blendFunc; color_t m_mask_color; public: - BlenderHelper(const Image* src, const Palette* pal, BlendMode blend_mode) + BlenderHelper(const Image* src, const Palette* pal, BlendMode blendMode) { - m_blend_mode = blend_mode; - m_blend_func = RgbTraits::get_blender(blend_mode); + m_blendMode = blendMode; + m_blendFunc = RgbTraits::get_blender(blendMode); m_mask_color = src->maskColor(); m_pal = pal; } @@ -89,12 +91,12 @@ public: const IndexedTraits::pixel_t& src, int opacity) { - if (m_blend_mode == BlendMode::SRC) { + if (m_blendMode == BlendMode::SRC) { return m_pal->getEntry(src); } else { if (src != m_mask_color) { - return (*m_blend_func)(dst, m_pal->getEntry(src), opacity); + return (*m_blendFunc)(dst, m_pal->getEntry(src), opacity); } else return dst; @@ -104,12 +106,12 @@ public: template<> class BlenderHelper<IndexedTraits, IndexedTraits> { - BlendMode m_blend_mode; + BlendMode m_blendMode; color_t m_mask_color; public: - BlenderHelper(const Image* src, const Palette* pal, BlendMode blend_mode) + BlenderHelper(const Image* src, const Palette* pal, BlendMode blendMode) { - m_blend_mode = blend_mode; + m_blendMode = blendMode; m_mask_color = src->maskColor(); } inline IndexedTraits::pixel_t @@ -117,7 +119,7 @@ public: const IndexedTraits::pixel_t& src, int opacity) { - if (m_blend_mode == BlendMode::SRC) { + if (m_blendMode == BlendMode::SRC) { return src; } else { @@ -130,19 +132,78 @@ public: }; template<class DstTraits, class SrcTraits> -static void compose_scaled_image_scale_up( - Image* dst, const Image* src, const Palette* pal, - gfx::Clip area, - int opacity, BlendMode blend_mode, Zoom zoom) +void composite_image_without_scale( + Image* dst, + const Image* src, + const Palette* pal, + const gfx::Clip& _area, + const int opacity, + const BlendMode blendMode, + const Zoom& zoom) { ASSERT(dst); ASSERT(src); ASSERT(DstTraits::pixel_format == dst->pixelFormat()); ASSERT(SrcTraits::pixel_format == src->pixelFormat()); - BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); + BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blendMode); + + gfx::Clip area = _area; + if (!area.clip(dst->width(), dst->height(), + src->width(), src->height())) + return; + + gfx::Rect srcBounds = area.srcBounds(); + gfx::Rect dstBounds = area.dstBounds(); + int bottom = area.dst.y+area.size.h-1; + + ASSERT(!srcBounds.isEmpty()); + + // Lock all necessary bits + const LockImageBits<SrcTraits> srcBits(src, srcBounds); + LockImageBits<DstTraits> dstBits(dst, dstBounds); + typename LockImageBits<SrcTraits>::const_iterator src_it = srcBits.begin(); + typename LockImageBits<SrcTraits>::const_iterator src_end = srcBits.end(); + typename LockImageBits<DstTraits>::iterator dst_it, dst_end; + + // For each line to draw of the source image... + dstBounds.h = 1; + for (int y=0; y<srcBounds.h; ++y) { + dst_it = dstBits.begin_area(dstBounds); + dst_end = dstBits.end_area(dstBounds); + + for (int x=0; x<srcBounds.w; ++x) { + ASSERT(src_it >= srcBits.begin() && src_it < src_end); + ASSERT(dst_it >= dstBits.begin() && dst_it < dst_end); + *dst_it = blender(*dst_it, *src_it, opacity); + ++src_it; + ++dst_it; + } + + if (++dstBounds.y > bottom) + break; + } +} + +template<class DstTraits, class SrcTraits> +void composite_image_scale_up( + Image* dst, + const Image* src, + const Palette* pal, + const gfx::Clip& _area, + const int opacity, + const BlendMode blendMode, + const Zoom& zoom) +{ + ASSERT(dst); + ASSERT(src); + ASSERT(DstTraits::pixel_format == dst->pixelFormat()); + ASSERT(SrcTraits::pixel_format == src->pixelFormat()); + + BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blendMode); int px_x, px_y; + gfx::Clip area = _area; if (!area.clip(dst->width(), dst->height(), zoom.apply(src->width()), zoom.apply(src->height()))) @@ -262,20 +323,23 @@ done_with_blit:; } template<class DstTraits, class SrcTraits> -static void compose_scaled_image_scale_down( +void composite_image_scale_down( Image* dst, const Image* src, const Palette* pal, - gfx::Clip area, - int opacity, BlendMode blend_mode, Zoom zoom) + const gfx::Clip& _area, + const int opacity, + const BlendMode blendMode, + const Zoom& zoom) { ASSERT(dst); ASSERT(src); ASSERT(DstTraits::pixel_format == dst->pixelFormat()); ASSERT(SrcTraits::pixel_format == src->pixelFormat()); - BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blend_mode); + BlenderHelper<DstTraits, SrcTraits> blender(src, pal, blendMode); int unbox_w = zoom.remove(1); int unbox_h = zoom.remove(1); + gfx::Clip area = _area; if (!area.clip(dst->width(), dst->height(), zoom.apply(src->width()), zoom.apply(src->height()))) @@ -324,17 +388,53 @@ static void compose_scaled_image_scale_down( } template<class DstTraits, class SrcTraits> -static void compose_scaled_image( - Image* dst, const Image* src, const Palette* pal, - const gfx::Clip& area, - int opacity, BlendMode blend_mode, Zoom zoom) +CompositeImageFunc get_image_composition_impl(Zoom zoom) { - if (zoom.scale() >= 1.0) - compose_scaled_image_scale_up<DstTraits, SrcTraits>(dst, src, pal, area, opacity, blend_mode, zoom); + if (zoom.scale() == 1.0) + return composite_image_without_scale<DstTraits, SrcTraits>; + else if (zoom.scale() > 1.0) + return composite_image_scale_up<DstTraits, SrcTraits>; else - compose_scaled_image_scale_down<DstTraits, SrcTraits>(dst, src, pal, area, opacity, blend_mode, zoom); + return composite_image_scale_down<DstTraits, SrcTraits>; } +CompositeImageFunc get_image_composition(PixelFormat dstFormat, + PixelFormat srcFormat, + const Zoom& zoom) +{ + switch (srcFormat) { + + case IMAGE_RGB: + switch (dstFormat) { + case IMAGE_RGB: return get_image_composition_impl<RgbTraits, RgbTraits>(zoom); + case IMAGE_GRAYSCALE: return get_image_composition_impl<GrayscaleTraits, RgbTraits>(zoom); + case IMAGE_INDEXED: return get_image_composition_impl<IndexedTraits, RgbTraits>(zoom); + } + break; + + case IMAGE_GRAYSCALE: + switch (dstFormat) { + case IMAGE_RGB: return get_image_composition_impl<RgbTraits, GrayscaleTraits>(zoom); + case IMAGE_GRAYSCALE: return get_image_composition_impl<GrayscaleTraits, GrayscaleTraits>(zoom); + case IMAGE_INDEXED: return get_image_composition_impl<IndexedTraits, GrayscaleTraits>(zoom); + } + break; + + case IMAGE_INDEXED: + switch (dstFormat) { + case IMAGE_RGB: return get_image_composition_impl<RgbTraits, IndexedTraits>(zoom); + case IMAGE_GRAYSCALE: return get_image_composition_impl<GrayscaleTraits, IndexedTraits>(zoom); + case IMAGE_INDEXED: return get_image_composition_impl<IndexedTraits, IndexedTraits>(zoom); + } + break; + } + + ASSERT(false && "Invalid pixel formats"); + return NULL; +} + +} // anonymous namespace + Render::Render() : m_sprite(NULL) , m_currentLayer(NULL) @@ -454,22 +554,22 @@ void Render::renderLayer( const Layer* layer, frame_t frame, const gfx::Clip& area, - BlendMode blend_mode) + BlendMode blendMode) { m_sprite = layer->sprite(); - RenderScaledImage scaled_func = - getRenderScaledImageFunc( + CompositeImageFunc compositeImage = + get_image_composition( dstImage->pixelFormat(), - m_sprite->pixelFormat()); - if (!scaled_func) + m_sprite->pixelFormat(), Zoom(1, 1)); + if (!compositeImage) return; m_globalOpacity = 255; renderLayer( layer, dstImage, area, - frame, Zoom(1, 1), scaled_func, - true, true, blend_mode); + frame, Zoom(1, 1), compositeImage, + true, true, blendMode); } void Render::renderSprite( @@ -481,11 +581,11 @@ void Render::renderSprite( { m_sprite = sprite; - RenderScaledImage scaled_func = - getRenderScaledImageFunc( + CompositeImageFunc compositeImage = + get_image_composition( dstImage->pixelFormat(), - m_sprite->pixelFormat()); - if (!scaled_func) + m_sprite->pixelFormat(), zoom); + if (!compositeImage) return; const LayerImage* bgLayer = m_sprite->backgroundLayer(); @@ -530,27 +630,27 @@ void Render::renderSprite( m_globalOpacity = 255; renderLayer( m_sprite->folder(), dstImage, - area, frame, zoom, scaled_func, + area, frame, zoom, compositeImage, true, false, BlendMode::UNSPECIFIED); // Draw onion skin behind the sprite. if (m_onionskin.position() == OnionskinPosition::BEHIND) - renderOnionskin(dstImage, area, frame, zoom, scaled_func); + renderOnionskin(dstImage, area, frame, zoom, compositeImage); // Draw the transparent layers. m_globalOpacity = 255; renderLayer( m_sprite->folder(), dstImage, - area, frame, zoom, scaled_func, + area, frame, zoom, compositeImage, false, true, BlendMode::UNSPECIFIED); // Draw onion skin in front of the sprite. if (m_onionskin.position() == OnionskinPosition::INFRONT) - renderOnionskin(dstImage, area, frame, zoom, scaled_func); + renderOnionskin(dstImage, area, frame, zoom, compositeImage); // Overlay preview image if (m_previewImage && @@ -562,7 +662,7 @@ void Render::renderSprite( m_sprite->palette(frame), 0, 0, area, - scaled_func, + compositeImage, 255, m_previewBlendMode, zoom); @@ -573,7 +673,7 @@ void Render::renderOnionskin( Image* dstImage, const gfx::Clip& area, frame_t frame, Zoom zoom, - RenderScaledImage scaled_func) + CompositeImageFunc compositeImage) { // Onion-skin feature: Draw previous/next frames with different // opacity (<255) @@ -612,21 +712,21 @@ void Render::renderOnionskin( m_globalOpacity = MID(0, m_globalOpacity, 255); if (m_globalOpacity > 0) { - BlendMode blend_mode = BlendMode::UNSPECIFIED; + BlendMode blendMode = BlendMode::UNSPECIFIED; if (m_onionskin.type() == OnionskinType::MERGE) - blend_mode = BlendMode::NORMAL; + blendMode = BlendMode::NORMAL; else if (m_onionskin.type() == OnionskinType::RED_BLUE_TINT) - blend_mode = (frameOut < frame ? BlendMode::RED_TINT: BlendMode::BLUE_TINT); + blendMode = (frameOut < frame ? BlendMode::RED_TINT: BlendMode::BLUE_TINT); renderLayer( onionLayer, dstImage, - area, frameIn, zoom, scaled_func, + area, frameIn, zoom, compositeImage, // Render background only for "in-front" onion skinning and // when opacity is < 255 (m_globalOpacity < 255 && m_onionskin.position() == OnionskinPosition::INFRONT), true, - blend_mode); + blendMode); } } } @@ -681,19 +781,19 @@ void Render::renderBackground(Image* image, void Render::renderImage(Image* dst_image, const Image* src_image, const Palette* pal, int x, int y, - Zoom zoom, int opacity, BlendMode blend_mode) + Zoom zoom, int opacity, BlendMode blendMode) { - RenderScaledImage scaled_func = getRenderScaledImageFunc( + CompositeImageFunc compositeImage = get_image_composition( dst_image->pixelFormat(), - src_image->pixelFormat()); - if (!scaled_func) + src_image->pixelFormat(), zoom); + if (!compositeImage) return; - scaled_func(dst_image, src_image, pal, + compositeImage(dst_image, src_image, pal, gfx::Clip(x, y, 0, 0, zoom.apply(src_image->width()), zoom.apply(src_image->height())), - opacity, blend_mode, zoom); + opacity, blendMode, zoom); } void Render::renderLayer( @@ -701,10 +801,10 @@ void Render::renderLayer( Image *image, const gfx::Clip& area, frame_t frame, Zoom zoom, - RenderScaledImage scaled_func, + CompositeImageFunc compositeImage, bool render_background, bool render_transparent, - BlendMode blend_mode) + BlendMode blendMode) { // we can't read from this layer if (!layer->isVisible()) @@ -761,9 +861,9 @@ void Render::renderLayer( if (src_image) { const LayerImage* imgLayer = static_cast<const LayerImage*>(layer); BlendMode layerBlendMode = - (blend_mode == BlendMode::UNSPECIFIED ? + (blendMode == BlendMode::UNSPECIFIED ? imgLayer->blendMode(): - blend_mode); + blendMode); ASSERT(cel->opacity() >= 0); ASSERT(cel->opacity() <= 255); @@ -788,7 +888,7 @@ void Render::renderLayer( renderCel( image, src_image, pal, cel, gfx::Clip(area.dst.x+rc.x-area.src.x, - area.dst.y+rc.y-area.src.y, rc), scaled_func, + area.dst.y+rc.y-area.src.y, rc), compositeImage, opacity, layerBlendMode, zoom); } } @@ -796,7 +896,7 @@ void Render::renderLayer( else { renderCel( image, src_image, pal, - cel, area, scaled_func, + cel, area, compositeImage, opacity, layerBlendMode, zoom); } } @@ -810,10 +910,10 @@ void Render::renderLayer( for (; it != end; ++it) { renderLayer(*it, image, - area, frame, zoom, scaled_func, + area, frame, zoom, compositeImage, render_background, render_transparent, - blend_mode); + blendMode); } break; } @@ -830,7 +930,7 @@ void Render::renderLayer( gfx::Clip(area.dst.x+extraArea.x-area.src.x, area.dst.y+extraArea.y-area.src.y, extraArea), - scaled_func, + compositeImage, m_extraCel->opacity(), m_extraBlendMode, zoom); } @@ -843,8 +943,8 @@ void Render::renderCel( const Palette* pal, const Cel* cel, const gfx::Clip& area, - RenderScaledImage scaled_func, - int opacity, BlendMode blend_mode, Zoom zoom) + CompositeImageFunc compositeImage, + int opacity, BlendMode blendMode, Zoom zoom) { renderImage(dst_image, cel_image, @@ -852,9 +952,9 @@ void Render::renderCel( cel->x(), cel->y(), area, - scaled_func, + compositeImage, opacity, - blend_mode, + blendMode, zoom); } @@ -865,8 +965,8 @@ void Render::renderImage( const int x, const int y, const gfx::Clip& area, - RenderScaledImage scaled_func, - int opacity, BlendMode blend_mode, Zoom zoom) + CompositeImageFunc compositeImage, + int opacity, BlendMode blendMode, Zoom zoom) { int cel_x = zoom.apply(x); int cel_y = zoom.apply(y); @@ -881,7 +981,7 @@ void Render::renderImage( if (src_bounds.isEmpty()) return; - (*scaled_func)(dst_image, cel_image, pal, + (*compositeImage)(dst_image, cel_image, pal, gfx::Clip( area.dst.x + src_bounds.x - area.src.x, area.dst.y + src_bounds.y - area.src.y, @@ -889,55 +989,22 @@ void Render::renderImage( src_bounds.y - cel_y, src_bounds.w, src_bounds.h), - opacity, blend_mode, zoom); -} - -// static -Render::RenderScaledImage Render::getRenderScaledImageFunc( - PixelFormat dstFormat, - PixelFormat srcFormat) -{ - switch (srcFormat) { - - case IMAGE_RGB: - switch (dstFormat) { - case IMAGE_RGB: return compose_scaled_image<RgbTraits, RgbTraits>; - case IMAGE_GRAYSCALE: return compose_scaled_image<GrayscaleTraits, RgbTraits>; - case IMAGE_INDEXED: return compose_scaled_image<IndexedTraits, RgbTraits>; - } - break; - - case IMAGE_GRAYSCALE: - switch (dstFormat) { - case IMAGE_RGB: return compose_scaled_image<RgbTraits, GrayscaleTraits>; - case IMAGE_GRAYSCALE: return compose_scaled_image<GrayscaleTraits, GrayscaleTraits>; - case IMAGE_INDEXED: return compose_scaled_image<IndexedTraits, GrayscaleTraits>; - } - break; - - case IMAGE_INDEXED: - switch (dstFormat) { - case IMAGE_RGB: return compose_scaled_image<RgbTraits, IndexedTraits>; - case IMAGE_GRAYSCALE: return compose_scaled_image<GrayscaleTraits, IndexedTraits>; - case IMAGE_INDEXED: return compose_scaled_image<IndexedTraits, IndexedTraits>; - } - break; - } - - ASSERT(false && "Invalid pixel formats"); - return NULL; + opacity, blendMode, zoom); } -void composite_image(Image* dst, const Image* src, +void composite_image(Image* dst, + const Image* src, const Palette* pal, - int x, int y, - int opacity, BlendMode blend_mode) + const int x, + const int y, + const int opacity, + const BlendMode blendMode) { // As the background is not rendered in renderImage(), we don't need // to configure the Render instance's BgType. Render().renderImage( dst, src, pal, x, y, Zoom(1, 1), - opacity, blend_mode); + opacity, blendMode); } } // namespace render diff --git a/src/render/render.h b/src/render/render.h index 93a6dbe..9c57447 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -89,6 +89,15 @@ namespace render { Layer* m_layer; }; + typedef void (*CompositeImageFunc)( + Image* dst, + const Image* src, + const Palette* pal, + const gfx::Clip& area, + const int opacity, + const BlendMode blendMode, + const Zoom& zoom); + class Render { public: Render(); @@ -139,7 +148,7 @@ namespace render { const Layer* layer, frame_t frame, const gfx::Clip& area, - BlendMode blend_mode = BlendMode::UNSPECIFIED); + BlendMode blendMode = BlendMode::UNSPECIFIED); // Main function used to render the sprite. Draws the given sprite // frame in a new image and return it. Note: zoomedRect must have @@ -158,29 +167,24 @@ namespace render { void renderImage(Image* dst_image, const Image* src_image, const Palette* pal, int x, int y, Zoom zoom, - int opacity, BlendMode blend_mode); + int opacity, BlendMode blendMode); private: - typedef void (*RenderScaledImage)( - Image* dst, const Image* src, const Palette* pal, - const gfx::Clip& area, - int opacity, BlendMode blend_mode, Zoom zoom); - void renderOnionskin( Image* image, const gfx::Clip& area, frame_t frame, Zoom zoom, - RenderScaledImage scaled_func); + CompositeImageFunc compositeImage); void renderLayer( const Layer* layer, Image* image, const gfx::Clip& area, frame_t frame, Zoom zoom, - RenderScaledImage renderScaledImage, + CompositeImageFunc compositeImage, bool render_background, bool render_transparent, - BlendMode blend_mode); + BlendMode blendMode); void renderCel( Image* dst_image, @@ -188,8 +192,8 @@ namespace render { const Palette* pal, const Cel* cel, const gfx::Clip& area, - RenderScaledImage scaled_func, - int opacity, BlendMode blend_mode, Zoom zoom); + CompositeImageFunc compositeImage, + int opacity, BlendMode blendMode, Zoom zoom); void renderImage( Image* dst_image, @@ -198,12 +202,8 @@ namespace render { const int x, const int y, const gfx::Clip& area, - RenderScaledImage scaled_func, - int opacity, BlendMode blend_mode, Zoom zoom); - - static RenderScaledImage getRenderScaledImageFunc( - PixelFormat dstFormat, - PixelFormat srcFormat); + CompositeImageFunc compositeImage, + int opacity, BlendMode blendMode, Zoom zoom); const Sprite* m_sprite; const Layer* m_currentLayer; @@ -226,10 +226,13 @@ namespace render { OnionskinOptions m_onionskin; }; - void composite_image(Image* dst, const Image* src, + void composite_image(Image* dst, + const Image* src, const Palette* pal, - int x, int y, - int opacity, BlendMode blend_mode); + const int x, + const int y, + const int opacity, + const BlendMode blendMode); } // namespace render -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits