OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2010 Google Inc. All rights reserved. | 3 * Copyright (C) 2010 Google Inc. All rights reserved. |
4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. | 4 * Copyright (C) 2010 Mozilla Corporation. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 } | 80 } |
81 | 81 |
82 } // anonymous namespace | 82 } // anonymous namespace |
83 | 83 |
84 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we
bContext, bool preserveDrawingBuffer) | 84 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3D> we
bContext, bool preserveDrawingBuffer) |
85 : m_impl(webContext.get()) | 85 : m_impl(webContext.get()) |
86 , m_ownedWebContext(webContext) | 86 , m_ownedWebContext(webContext) |
87 , m_initializedAvailableExtensions(false) | 87 , m_initializedAvailableExtensions(false) |
88 , m_layerComposited(false) | 88 , m_layerComposited(false) |
89 , m_preserveDrawingBuffer(preserveDrawingBuffer) | 89 , m_preserveDrawingBuffer(preserveDrawingBuffer) |
| 90 , m_packAlignment(4) |
90 , m_resourceSafety(ResourceSafetyUnknown) | 91 , m_resourceSafety(ResourceSafetyUnknown) |
91 , m_grContext(0) | 92 , m_grContext(0) |
92 { | 93 { |
93 } | 94 } |
94 | 95 |
95 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProv
ider> provider, bool preserveDrawingBuffer) | 96 GraphicsContext3D::GraphicsContext3D(PassOwnPtr<WebKit::WebGraphicsContext3DProv
ider> provider, bool preserveDrawingBuffer) |
96 : m_provider(provider) | 97 : m_provider(provider) |
97 , m_impl(m_provider->context3d()) | 98 , m_impl(m_provider->context3d()) |
98 , m_initializedAvailableExtensions(false) | 99 , m_initializedAvailableExtensions(false) |
99 , m_layerComposited(false) | 100 , m_layerComposited(false) |
100 , m_preserveDrawingBuffer(preserveDrawingBuffer) | 101 , m_preserveDrawingBuffer(preserveDrawingBuffer) |
| 102 , m_packAlignment(4) |
101 , m_resourceSafety(ResourceSafetyUnknown) | 103 , m_resourceSafety(ResourceSafetyUnknown) |
102 , m_grContext(m_provider->grContext()) | 104 , m_grContext(m_provider->grContext()) |
103 { | 105 { |
104 } | 106 } |
105 | 107 |
106 GraphicsContext3D::~GraphicsContext3D() | 108 GraphicsContext3D::~GraphicsContext3D() |
107 { | 109 { |
108 setContextLostCallback(nullptr); | 110 setContextLostCallback(nullptr); |
109 setErrorMessageCallback(nullptr); | 111 setErrorMessageCallback(nullptr); |
110 | 112 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) | 495 DELEGATE_TO_WEBCONTEXT_2(hint, GC3Denum, GC3Denum) |
494 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) | 496 DELEGATE_TO_WEBCONTEXT_1R(isBuffer, Platform3DObject, GC3Dboolean) |
495 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) | 497 DELEGATE_TO_WEBCONTEXT_1R(isEnabled, GC3Denum, GC3Dboolean) |
496 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) | 498 DELEGATE_TO_WEBCONTEXT_1R(isFramebuffer, Platform3DObject, GC3Dboolean) |
497 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) | 499 DELEGATE_TO_WEBCONTEXT_1R(isProgram, Platform3DObject, GC3Dboolean) |
498 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) | 500 DELEGATE_TO_WEBCONTEXT_1R(isRenderbuffer, Platform3DObject, GC3Dboolean) |
499 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) | 501 DELEGATE_TO_WEBCONTEXT_1R(isShader, Platform3DObject, GC3Dboolean) |
500 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) | 502 DELEGATE_TO_WEBCONTEXT_1R(isTexture, Platform3DObject, GC3Dboolean) |
501 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) | 503 DELEGATE_TO_WEBCONTEXT_1(lineWidth, GC3Dfloat) |
502 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) | 504 DELEGATE_TO_WEBCONTEXT_1(linkProgram, Platform3DObject) |
503 DELEGATE_TO_WEBCONTEXT_2(pixelStorei, GC3Denum, GC3Dint) | 505 |
| 506 void GraphicsContext3D::pixelStorei(GC3Denum pname, GC3Dint param) |
| 507 { |
| 508 if (pname == PACK_ALIGNMENT) |
| 509 m_packAlignment = param; |
| 510 m_impl->pixelStorei(pname, param); |
| 511 } |
| 512 |
504 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) | 513 DELEGATE_TO_WEBCONTEXT_2(polygonOffset, GC3Dfloat, GC3Dfloat) |
505 | 514 |
506 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) | 515 DELEGATE_TO_WEBCONTEXT_7(readPixels, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei, GC3
Denum, GC3Denum, void*) |
507 | 516 |
508 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) | 517 DELEGATE_TO_WEBCONTEXT(releaseShaderCompiler) |
509 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) | 518 DELEGATE_TO_WEBCONTEXT_4(renderbufferStorage, GC3Denum, GC3Denum, GC3Dsizei, GC3
Dsizei) |
510 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) | 519 DELEGATE_TO_WEBCONTEXT_2(sampleCoverage, GC3Dclampf, GC3Dboolean) |
511 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) | 520 DELEGATE_TO_WEBCONTEXT_4(scissor, GC3Dint, GC3Dint, GC3Dsizei, GC3Dsizei) |
512 | 521 |
513 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) | 522 void GraphicsContext3D::shaderSource(Platform3DObject shader, const String& stri
ng) |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 { | 606 { |
598 if (getContextAttributes().premultipliedAlpha) | 607 if (getContextAttributes().premultipliedAlpha) |
599 return 0; | 608 return 0; |
600 | 609 |
601 Platform3DObject framebufferId; | 610 Platform3DObject framebufferId; |
602 int width, height; | 611 int width, height; |
603 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; | 612 getDrawingParameters(drawingBuffer, m_impl, &framebufferId, &width, &height)
; |
604 | 613 |
605 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); | 614 RefPtr<ImageData> imageData = ImageData::create(IntSize(width, height)); |
606 unsigned char* pixels = imageData->data()->data(); | 615 unsigned char* pixels = imageData->data()->data(); |
607 size_t bufferSize = 4 * width * height; | |
608 | 616 |
609 m_impl->readBackFramebuffer(pixels, bufferSize, framebufferId, width, height
); | 617 m_impl->bindFramebuffer(FRAMEBUFFER, framebufferId); |
610 | 618 readBackFramebuffer(pixels, width, height, ReadbackRGBA, AlphaDoNothing); |
611 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT | 619 flipVertically(pixels, width, height); |
612 // If the implementation swapped the red and blue channels, un-swap them. | |
613 for (size_t i = 0; i < bufferSize; i += 4) | |
614 std::swap(pixels[i], pixels[i + 2]); | |
615 #endif | |
616 | 620 |
617 return imageData.release(); | 621 return imageData.release(); |
618 } | 622 } |
619 | 623 |
| 624 void GraphicsContext3D::readBackFramebuffer(unsigned char* pixels, int width, in
t height, ReadbackOrder readbackOrder, AlphaOp op) |
| 625 { |
| 626 if (m_packAlignment > 4) |
| 627 m_impl->pixelStorei(PACK_ALIGNMENT, 1); |
| 628 m_impl->readPixels(0, 0, width, height, RGBA, UNSIGNED_BYTE, pixels); |
| 629 if (m_packAlignment > 4) |
| 630 m_impl->pixelStorei(PACK_ALIGNMENT, m_packAlignment); |
| 631 |
| 632 size_t bufferSize = 4 * width * height; |
| 633 |
| 634 if (readbackOrder == ReadbackSkia) { |
| 635 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT |
| 636 // Swizzle red and blue channels to match SkBitmap's byte ordering. |
| 637 // TODO(kbr): expose GL_BGRA as extension. |
| 638 for (size_t i = 0; i < bufferSize; i += 4) { |
| 639 std::swap(pixels[i], pixels[i + 2]); |
| 640 } |
| 641 #endif |
| 642 } |
| 643 |
| 644 if (op == AlphaDoPremultiply) { |
| 645 for (size_t i = 0; i < bufferSize; i += 4) { |
| 646 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); |
| 647 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); |
| 648 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); |
| 649 } |
| 650 } else if (op != AlphaDoNothing) { |
| 651 ASSERT_NOT_REACHED(); |
| 652 } |
| 653 } |
| 654 |
620 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) | 655 DELEGATE_TO_WEBCONTEXT_R(createBuffer, Platform3DObject) |
621 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) | 656 DELEGATE_TO_WEBCONTEXT_R(createFramebuffer, Platform3DObject) |
622 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) | 657 DELEGATE_TO_WEBCONTEXT_R(createProgram, Platform3DObject) |
623 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) | 658 DELEGATE_TO_WEBCONTEXT_R(createRenderbuffer, Platform3DObject) |
624 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) | 659 DELEGATE_TO_WEBCONTEXT_1R(createShader, GC3Denum, Platform3DObject) |
625 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) | 660 DELEGATE_TO_WEBCONTEXT_R(createTexture, Platform3DObject) |
626 | 661 |
627 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) | 662 DELEGATE_TO_WEBCONTEXT_1(deleteBuffer, Platform3DObject) |
628 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) | 663 DELEGATE_TO_WEBCONTEXT_1(deleteFramebuffer, Platform3DObject) |
629 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) | 664 DELEGATE_TO_WEBCONTEXT_1(deleteProgram, Platform3DObject) |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
883 case GraphicsContext3D::DEPTH_STENCIL: | 918 case GraphicsContext3D::DEPTH_STENCIL: |
884 return ChannelDepth | ChannelStencil; | 919 return ChannelDepth | ChannelStencil; |
885 default: | 920 default: |
886 return 0; | 921 return 0; |
887 } | 922 } |
888 } | 923 } |
889 | 924 |
890 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) | 925 void GraphicsContext3D::paintFramebufferToCanvas(int framebuffer, int width, int
height, bool premultiplyAlpha, ImageBuffer* imageBuffer) |
891 { | 926 { |
892 unsigned char* pixels = 0; | 927 unsigned char* pixels = 0; |
893 size_t bufferSize = 4 * width * height; | |
894 | 928 |
895 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); | 929 const SkBitmap* canvasBitmap = imageBuffer->context()->bitmap(); |
896 const SkBitmap* readbackBitmap = 0; | 930 const SkBitmap* readbackBitmap = 0; |
897 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); | 931 ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); |
898 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { | 932 if (canvasBitmap->width() == width && canvasBitmap->height() == height) { |
899 // This is the fastest and most common case. We read back | 933 // This is the fastest and most common case. We read back |
900 // directly into the canvas's backing store. | 934 // directly into the canvas's backing store. |
901 readbackBitmap = canvasBitmap; | 935 readbackBitmap = canvasBitmap; |
902 m_resizingBitmap.reset(); | 936 m_resizingBitmap.reset(); |
903 } else { | 937 } else { |
904 // We need to allocate a temporary bitmap for reading back the | 938 // We need to allocate a temporary bitmap for reading back the |
905 // pixel data. We will then use Skia to rescale this bitmap to | 939 // pixel data. We will then use Skia to rescale this bitmap to |
906 // the size of the canvas's backing store. | 940 // the size of the canvas's backing store. |
907 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { | 941 if (m_resizingBitmap.width() != width || m_resizingBitmap.height() != he
ight) { |
908 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); | 942 m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, heigh
t); |
909 if (!m_resizingBitmap.allocPixels()) | 943 if (!m_resizingBitmap.allocPixels()) |
910 return; | 944 return; |
911 } | 945 } |
912 readbackBitmap = &m_resizingBitmap; | 946 readbackBitmap = &m_resizingBitmap; |
913 } | 947 } |
914 | 948 |
915 // Read back the frame buffer. | 949 // Read back the frame buffer. |
916 SkAutoLockPixels bitmapLock(*readbackBitmap); | 950 SkAutoLockPixels bitmapLock(*readbackBitmap); |
917 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); | 951 pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); |
918 | 952 |
919 m_impl->readBackFramebuffer(pixels, 4 * width * height, framebuffer, width,
height); | 953 m_impl->bindFramebuffer(FRAMEBUFFER, framebuffer); |
920 | 954 readBackFramebuffer(pixels, width, height, ReadbackSkia, premultiplyAlpha ?
AlphaDoPremultiply : AlphaDoNothing); |
921 if (premultiplyAlpha) { | 955 flipVertically(pixels, width, height); |
922 for (size_t i = 0; i < bufferSize; i += 4) { | |
923 pixels[i + 0] = std::min(255, pixels[i + 0] * pixels[i + 3] / 255); | |
924 pixels[i + 1] = std::min(255, pixels[i + 1] * pixels[i + 3] / 255); | |
925 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); | |
926 } | |
927 } | |
928 | 956 |
929 readbackBitmap->notifyPixelsChanged(); | 957 readbackBitmap->notifyPixelsChanged(); |
930 if (m_resizingBitmap.readyToDraw()) { | 958 if (m_resizingBitmap.readyToDraw()) { |
931 // We need to draw the resizing bitmap into the canvas's backing store. | 959 // We need to draw the resizing bitmap into the canvas's backing store. |
932 SkCanvas canvas(*canvasBitmap); | 960 SkCanvas canvas(*canvasBitmap); |
933 SkRect dst; | 961 SkRect dst; |
934 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); | 962 dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->
width()), SkIntToScalar(canvasBitmap->height())); |
935 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); | 963 canvas.drawBitmapRect(m_resizingBitmap, 0, dst); |
936 } | 964 } |
937 } | 965 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 return m_enabledExtensions.contains(mappedName); | 1030 return m_enabledExtensions.contains(mappedName); |
1003 } | 1031 } |
1004 | 1032 |
1005 bool GraphicsContext3D::isExtensionEnabled(const String& name) | 1033 bool GraphicsContext3D::isExtensionEnabled(const String& name) |
1006 { | 1034 { |
1007 initializeExtensions(); | 1035 initializeExtensions(); |
1008 String mappedName = mapExtensionName(name); | 1036 String mappedName = mapExtensionName(name); |
1009 return m_enabledExtensions.contains(mappedName); | 1037 return m_enabledExtensions.contains(mappedName); |
1010 } | 1038 } |
1011 | 1039 |
| 1040 void GraphicsContext3D::flipVertically(uint8_t* framebuffer, int width, int heig
ht) |
| 1041 { |
| 1042 m_scanline.resize(width * 4); |
| 1043 uint8* scanline = &m_scanline[0]; |
| 1044 unsigned rowBytes = width * 4; |
| 1045 unsigned count = height / 2; |
| 1046 for (unsigned i = 0; i < count; i++) { |
| 1047 uint8* rowA = framebuffer + i * rowBytes; |
| 1048 uint8* rowB = framebuffer + (height - i - 1) * rowBytes; |
| 1049 memcpy(scanline, rowB, rowBytes); |
| 1050 memcpy(rowB, rowA, rowBytes); |
| 1051 memcpy(rowA, scanline, rowBytes); |
| 1052 } |
| 1053 } |
| 1054 |
1012 } // namespace WebCore | 1055 } // namespace WebCore |
OLD | NEW |