SuperImposeScalerOutput.cc 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #include "SuperImposeScalerOutput.hh"
  2. #include "RawFrame.hh"
  3. #include "LineScalers.hh"
  4. #include "MemoryOps.hh"
  5. #include "unreachable.hh"
  6. #include "vla.hh"
  7. #include "build-info.hh"
  8. #include <cstdint>
  9. namespace openmsx {
  10. template<typename Pixel>
  11. SuperImposeScalerOutput<Pixel>::SuperImposeScalerOutput(
  12. ScalerOutput<Pixel>& output_,
  13. const RawFrame& superImpose_,
  14. const PixelOperations<Pixel>& pixelOps_)
  15. : output(output_)
  16. , superImpose(superImpose_)
  17. , pixelOps(pixelOps_)
  18. {
  19. }
  20. template<typename Pixel>
  21. unsigned SuperImposeScalerOutput<Pixel>::getWidth() const
  22. {
  23. return output.getWidth();
  24. }
  25. template<typename Pixel>
  26. unsigned SuperImposeScalerOutput<Pixel>::getHeight() const
  27. {
  28. return output.getHeight();
  29. }
  30. template<typename Pixel>
  31. Pixel* SuperImposeScalerOutput<Pixel>::acquireLine(unsigned y)
  32. {
  33. return output.acquireLine(y);
  34. }
  35. template<typename Pixel>
  36. void SuperImposeScalerOutput<Pixel>::releaseLine(unsigned y, Pixel* buf)
  37. {
  38. unsigned width = output.getWidth();
  39. VLA_SSE_ALIGNED(Pixel, buf2, width);
  40. auto* srcLine = getSrcLine(y, buf2);
  41. AlphaBlendLines<Pixel> alphaBlend(pixelOps);
  42. alphaBlend(buf, srcLine, buf, width);
  43. output.releaseLine(y, buf);
  44. }
  45. template<typename Pixel>
  46. void SuperImposeScalerOutput<Pixel>::fillLine(unsigned y, Pixel color)
  47. {
  48. auto* dstLine = output.acquireLine(y);
  49. unsigned width = output.getWidth();
  50. if (pixelOps.isFullyOpaque(color)) {
  51. MemoryOps::MemSet<Pixel> memset;
  52. memset(dstLine, width, color);
  53. } else {
  54. auto* srcLine = getSrcLine(y, dstLine);
  55. if (pixelOps.isFullyTransparent(color)) {
  56. // optimization: use destination as work buffer, in case
  57. // that buffer got used, we don't need to make a copy
  58. // anymore
  59. if (srcLine != dstLine) {
  60. Scale_1on1<Pixel> copy;
  61. copy(srcLine, dstLine, width);
  62. }
  63. } else {
  64. AlphaBlendLines<Pixel> alphaBlend(pixelOps);
  65. alphaBlend(color, srcLine, dstLine, width); // possibly srcLine == dstLine
  66. }
  67. }
  68. output.releaseLine(y, dstLine);
  69. }
  70. template<typename Pixel>
  71. const Pixel* SuperImposeScalerOutput<Pixel>::getSrcLine(unsigned y, Pixel* buf)
  72. {
  73. unsigned width = output.getWidth();
  74. if (width == 320) {
  75. return superImpose.getLinePtr320_240(y, buf);
  76. } else if (width == 640) {
  77. return superImpose.getLinePtr640_480(y, buf);
  78. } else if (width == 960) {
  79. return superImpose.getLinePtr960_720(y, buf);
  80. } else {
  81. UNREACHABLE; return nullptr;
  82. }
  83. }
  84. // Force template instantiation.
  85. #if HAVE_16BPP
  86. template class SuperImposeScalerOutput<uint16_t>;
  87. #endif
  88. #if HAVE_32BPP
  89. template class SuperImposeScalerOutput<uint32_t>;
  90. #endif
  91. } // namespace openmsx